首頁  >  文章  >  web前端  >  nuxt框架中路由鑑權之Koa與Session使用方法

nuxt框架中路由鑑權之Koa與Session使用方法

php中世界最好的语言
php中世界最好的语言原創
2018-05-22 14:06:011888瀏覽

這次帶給大家nuxt框架中路由鑑權之Koa與Session使用方法,nuxt框架中路由鑑權之Koa與Session使用的注意事項有哪些,下面就是實戰案例,一起來看一下。

引子

部落格的後台管理頁面需要有登入系統,所以考慮做一下路由鑑權,實作方式也是Nuxt 官網給出栗子來改寫,順便也將前後端路由給統一了。

路由攔截

前端方面主要透過利用Nuxt 的中介軟體來做路由攔截,這裡也是需要Vuex狀態樹來做。

middleware

middleware/auth.js

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

透過對狀態樹上的使用者資訊是否存在來鑑權,來對頁面進行重定向

layouts/admin.vue

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

在後台管理系統的頁面佈局上新增中間件

nuxtServerInit

在NuxtJs 的渲染流程中,當請求打入時,最先呼叫的就是nuxtServerInit 方法,可以透過這個方法預先儲存伺服器的資料。

我們可以利用該方法來接收儲存使用者資訊的 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)
  }
 },

當應用程式完成時,一些我們從伺服器取得的資料就會被填入這個狀態樹 (store) 上。

依照NuxtJs 官網給出的栗子來看,到這裡基本算把頁面中路由鑑權部分寫完了,接下來是伺服器端該部分程式碼的寫作

使用Koa和koa-session

Koa和koa-session

後端程式碼我採用是Koa 框架,以及koa- session 來對Session 做處理。

在新建nuxt 專案的時候直接選用Koa 框架即可

vue init nuxt/koa

相關依賴

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()

對koa- session 的用法,可以參考:從koa-session中間件學習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: '密码错误'
 })
})
寫到這裡,整個功能流程基本上完畢了,也非常的順暢,但是對我來說一帆風順的程式碼是不存在的。

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 獲取不到有關session 的任何信息,然而其他的api 均可獲取到session ,當時由於苦苦找不到原因,一度懷疑栗子有問題。 。

原因

最終的問題還是因為自己的粗心,忽略了一些細節,在官網給出的栗子中:

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也確實存在於req.session ,而我使用的Koa2 和Koa-session , Koa-session 將cookie 解析到了ctx.session , 它並不存在於req.session 。

解決

所以在將nuxt.render 注入的時候,將session 加入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)
   })
  })
 })
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

jQuery實作模糊查詢步驟詳解

node Async/Await 非同步程式實作詳解

以上是nuxt框架中路由鑑權之Koa與Session使用方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn