亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

nuxt框架中路由鑒權(quán)之Koa和Session的用法

 更新時(shí)間:2018年05月09日 15:36:42   作者:AdityaSui  
后臺(tái)管理頁(yè)面需要有登錄系統(tǒng),所以考慮做一下路由鑒權(quán),這篇文章主要介紹了nuxt框架中路由鑒權(quán)之Koa和Session的用法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

引子

博客的后臺(tái)管理頁(yè)面需要有登錄系統(tǒng),所以考慮做一下路由鑒權(quán),實(shí)現(xiàn)方式也是 Nuxt 官網(wǎng)給出栗子來(lái)改寫,順便也將前后端路由給統(tǒng)一了。

路由攔截

前端方面主要通過(guò)利用 Nuxt 的中間件來(lái)做路由攔截,這里也是需要 Vuex 狀態(tài)樹來(lái)做。

middleware

middleware/auth.js

export default function ({ store, redirect }) {
 
 if (!store.state.user) {
  return redirect('/login')
 }
}

通過(guò)對(duì)狀態(tài)樹上的用戶信息是否存在來(lái)鑒權(quán),來(lái)對(duì)頁(yè)面進(jìn)行重定向

layouts/admin.vue

export default {
  middleware: 'auth',
  components: {
   AdminAside
  }
 }

在后臺(tái)管理系統(tǒng)的頁(yè)面布局上添加 中間件

nuxtServerInit

在 NuxtJs 的渲染流程中,當(dāng)請(qǐng)求打入時(shí),最先調(diào)用的即是 nuxtServerInit 方法,可以通過(guò)這個(gè)方法預(yù)先將服務(wù)器的數(shù)據(jù)保存。

我們可以利用該方法來(lái)接收存儲(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)給出的栗子來(lái)看,到這里基本算把頁(yè)面中路由鑒權(quán)部分寫完了,接下來(lái)是對(duì)服務(wù)器端該部分代碼的寫作

使用Koa和koa-session

Koa和koa-session

后端代碼我采用是 Koa 框架,以及 koa-session 來(lái)對(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ì)我來(lái)說(shuō)一帆風(fēng)順的代碼是不存在的。

session is not defined

問(wèn)題

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í)由于苦苦找不到原因,一度懷疑栗子有問(wèn)題。。

原因

最終的問(wèn)題還是因?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)文章

最新評(píng)論