primers
The background management page of the blog needs to have a login system, so consider doing a route authentication, the implementation method is also Nuxt official website gives the kernel to rewrite, incidentally will also be the front and back end of the route to the unified.
Routing to intercept
The front end mainly uses Nuxt middleware to do route interception, which also requires Vuex state tree to do.
middleware
middleware/auth.js
Copy the code
export default function ({ store, redirect }) {
if(! store.state.user) {return redirect('/login')}}Copy the code
The page is redirected by authenticating whether the user information in the status tree exists
layouts/admin.vue
Copy the code
export default {
middleware: 'auth',
components: {
AdminAside
}
}
Copy the code
Add middleware to the page layout of background management system
nuxtServerInit
In the NuxtJs rendering process, when a request comes in, the nuxtServerInit method is called first, which saves the server’s data beforehand.
We can use this method to receive Session information that stores user information.
nuxtServerInit ({ commit }, { req, res }) {
if (req.session && req.session.user) {
const { username, password } = req.session.user
const user = {
username,
password
}
commit('SET_USER', user)
}
},
Copy the code
When the application is complete, some of the data we fetch from the server is filled into the state store.
According to the NuxtJs official website, the basic calculation of the page route authentication part is finished, the next part of the server code writing
Use Koa and KoA-session
Koa and Koa – the session
The backend code I use is Koa framework, and KOA-Session to do session processing.
When creating nuXT project, you can choose Koa framework directly
vue init nuxt/koa
Copy the code
Related,
npm install koa-session
Copy the code
Overwrite in server.js
import Koa from 'koa'
import { Nuxt, Builder } from 'nuxt'
// after end
import session from 'koa-session'
async function start () {
const app = new Koa()
const host = process.env.HOST || '127.0.0.1'
const port = process.env.PORT || 7998
// Import and Set Nuxt.js options
let config = require('.. /nuxt.config.js') config.dev = ! (app.env ==='production')
// Instantiate nuxt.js
const nuxt = new Nuxt(config)
// Build in development
if(config.dev) { const builder = new Builder(nuxt) await builder.build() } // body-parser app.use(bodyParser()) // mongodb // session app.keys = ['some session']
const CONFIG = {
key: 'SESSION', /** (string) cookie key (default is koa:sess) */
/** (number || 'session') maxAge in ms (default is 1 days) */
/** 'session' will result in a cookie that expires when session/browser is closed */
/** Warning: If a session cookie is stolen, this cookie will never expire */
maxAge: 86400000,
overwrite: true, /** (boolean) can overwrite or not (default true) */
httpOnly: true, /** (boolean) httpOnly or not (default true) */
signed: true, /** (boolean) signed or not (default true) */
rolling: false /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. default is false **/
}
app.use(session(CONFIG, app))
// routes
app.use(async (ctx, next) => {
await next()
ctx.status = 200 // koa defaults to 404 when it sees that status is unset
return new Promise((resolve, reject) => {
ctx.res.on('close', resolve)
ctx.res.on('finish', resolve)
nuxt.render(ctx.req, ctx.res, promise => {
// nuxt.render passes a rejected promise into callback on error.
promise.then(resolve).catch(reject)
})
})
})
app.listen(port, host)
console.log('Server listening on ' + host + ':' + port) // eslint-disable-line no-console
}
start()
Copy the code
For the usage of KOA-session, see: Learn cookies and sessions from the KOA-Session middleware
Log on to the routing
/ / login the router. Post ('/api/login', async (ctx, next) => {
const { username, password } = ctx.request.body
let user,
match
try {
user = await Admin.findOne({ user: username }).exec()
if (user) {
match = await user.comparePassword(password, user.password)
}
} catch (e) {
throw new Error(e)
}
if (match) {
ctx.session.user = {
_id: user._id,
username: user.user,
nickname: user.nickname,
role: user.role
}
console.log(ctx.session)
return (ctx.body = {
success: true,
data: {
username: user.user,
nickname: user.nickname
}
})
}
return (ctx.body = {
success: false,
err: 'Password error'})})Copy the code
At this point, the whole functional process is basically finished, and it is very smooth, but there is no such thing as plain sailing code for me.
session is not defined
The problem
nuxtServerInit ({ commit }, { req, res }) {
if (req.session && req.session.user) { // res.session is not defined
const { username, password } = req.session.user
const user = {
username,
password
}
commit('SET_USER', user)
}
}
Copy the code
NuxtServerInit does not obtain any information about sessions, while other apis can obtain sessions, at that time, because of hard to find the cause, I suspected that there was a problem.
why
The final problem is still due to my carelessness and neglect of some details. In the chestnut provided on the official website:
app.post('/api/login'.function (req, res) {
if (req.body.username === 'demo' && req.body.password === 'demo') {
req.session.authUser = { username: 'demo' }
return res.json({ username: 'demo' })
}
res.status(401).json({ error: 'Bad credentials'})})Copy the code
It saves the session in req.session, so in nuxtServerInit session does exist in req.session, and the Koa2 and KOa-sessions THAT I’m using, Koa-session resolves the cookie to ctx.session, which does not exist in req.session.
To solve
So add session to request when nuxt.render is injected
app.use(async (ctx, next) => {
await next()
ctx.status = 200 // koa defaults to 404 when it sees that status is unset
ctx.req.session = ctx.session
return new Promise((resolve, reject) => {
ctx.res.on('close', resolve)
ctx.res.on('finish', resolve)
nuxt.render(ctx.req, ctx.res, promise => {
// nuxt.render passes a rejected promise into callback on error.
promise.then(resolve).catch(reject)
})
})
})
Copy the code
And you’re done!