nuxt框架中路由鑒權(quán)之Koa和Session的用法
引子
博客的后臺(tái)管理頁面需要有登錄系統(tǒng),所以考慮做一下路由鑒權(quán),實(shí)現(xiàn)方式也是 Nuxt 官網(wǎng)給出栗子來改寫,順便也將前后端路由給統(tǒng)一了。
路由攔截
前端方面主要通過利用 Nuxt 的中間件來做路由攔截,這里也是需要 Vuex 狀態(tài)樹來做。
middleware
middleware/auth.js
export default function ({ store, redirect }) {
if (!store.state.user) {
return redirect('/login')
}
}
通過對(duì)狀態(tài)樹上的用戶信息是否存在來鑒權(quán),來對(duì)頁面進(jìn)行重定向
layouts/admin.vue
export default {
middleware: 'auth',
components: {
AdminAside
}
}
在后臺(tái)管理系統(tǒng)的頁面布局上添加 中間件
nuxtServerInit
在 NuxtJs 的渲染流程中,當(dāng)請(qǐng)求打入時(shí),最先調(diào)用的即是 nuxtServerInit 方法,可以通過這個(gè)方法預(yù)先將服務(wù)器的數(shù)據(jù)保存。
我們可以利用該方法來接收存儲(chǔ)用戶信息的 Session 信息。
nuxtServerInit ({ commit }, { req, res }) {
if (req.session && req.session.user) {
const { username, password } = req.session.user
const user = {
username,
password
}
commit('SET_USER', user)
}
},
當(dāng)應(yīng)用完畢時(shí),一些我們從服務(wù)器獲取到的數(shù)據(jù)就會(huì)被填充到這個(gè)狀態(tài)樹 (store) 上。
按照 NuxtJs 官網(wǎng)給出的栗子來看,到這里基本算把頁面中路由鑒權(quán)部分寫完了,接下來是對(duì)服務(wù)器端該部分代碼的寫作
使用Koa和koa-session
Koa和koa-session
后端代碼我采用是 Koa 框架,以及 koa-session 來對(duì) Session 做處理。
在新建 nuxt 項(xiàng)目的時(shí)候直接選用 Koa 框架即可
vue init nuxt/koa
相關(guān)依賴
npm install koa-session
在 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()
對(duì)于 koa-session 的用法,可以參考:從koa-session中間件學(xué)習(xí)cookie與session
登錄路由
// 登錄
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: '密碼錯(cuò)誤'
})
})
寫到這里,整個(gè)功能流程基本完畢了,也非常的順暢,但是對(duì)我來說一帆風(fēng)順的代碼是不存在的。
session is not defined
問題
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)
}
}
在 nuxtServerInit 獲取不到有關(guān) session 的任何信息,然而其他的 api 均可獲取到 session ,當(dāng)時(shí)由于苦苦找不到原因,一度懷疑栗子有問題。。
原因
最終的問題還是因?yàn)樽约旱拇中?,忽視了一些?xì)節(jié),在官網(wǎng)給出的栗子中:
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' })
})
它將 session 保存在了 req.session , 所以在 nuxtServerInit session也確實(shí)存在于 req.session ,而我使用的 Koa2 和 Koa-session , Koa-session 將 cookie 解析到了 ctx.session , 它并不存在于 req.session 。
解決
所以在將 nuxt.render 注入的時(shí)候,將 session 添加進(jìn) request 中
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)
})
})
})
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于element?ui的菜單default-active默認(rèn)選中的問題
這篇文章主要介紹了關(guān)于element?ui的菜單default-active默認(rèn)選中的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
用Vue-cli搭建的項(xiàng)目中引入css報(bào)錯(cuò)的原因分析
本篇文章主要介紹了用Vue-cli搭建的項(xiàng)目中引入css報(bào)錯(cuò)的原因分析,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Vue結(jié)合ElementUI上傳Base64編碼后的圖片實(shí)例
這篇文章主要介紹了Vue結(jié)合ElementUI上傳Base64編碼后的圖片實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
解決cordova+vue 項(xiàng)目打包成APK應(yīng)用遇到的問題
這篇文章主要介紹了解決cordova+vue 項(xiàng)目打包成APK應(yīng)用遇到的問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
Vue零基礎(chǔ)入門之模板語法與數(shù)據(jù)綁定及Object.defineProperty方法詳解
這篇文章主要介紹了Vue初學(xué)基礎(chǔ)中的模板語法、數(shù)據(jù)綁定、Object.defineProperty方法等基礎(chǔ),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09
詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法
本篇文章主要介紹了詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法,在VUE開發(fā)時(shí),數(shù)據(jù)可以使用jquery和vue-resource來獲取數(shù)據(jù),有興趣的可以了解一下。2017-01-01

