博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nuxt框架中路由鉴权——Koa和Session
阅读量:6682 次
发布时间:2019-06-25

本文共 5120 字,大约阅读时间需要 17 分钟。

引子

博客的后台管理页面需要有登录系统,所以考虑做一下路由鉴权,实现方式也是 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 endimport 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 的用法,可以参考:

登录路由

// 登录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-sessionKoa-sessioncookie 解析到了 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)      })    })  })复制代码

大功告成!

转载地址:http://sdaao.baihongyu.com/

你可能感兴趣的文章
APUE读书笔记-09进程关系(02)
查看>>
来南京工作两个月了!
查看>>
EDM邮件营销的七个基本原则
查看>>
dropna(thresh=n) 的用法
查看>>
谨慎Asp.net中static变量的用法
查看>>
Harbor镜像仓库漏洞扫描功能
查看>>
git(学习之四)git协议服务器搭建
查看>>
我的友情链接
查看>>
实现hive proxy4-scratch目录权限问题解决
查看>>
杂谈(20)写给妹妹的信-完整版
查看>>
边界在消失——2014年七大技术趋势预测
查看>>
综合考虑各系统的平衡——中科曙光数据中心产品事业部总经理沈卫东谈云数据中心节能...
查看>>
MongoDB +node.js图片读取服务
查看>>
关于jmeter里的自动重定向的使用-小强性能测试培训班学生作品
查看>>
我的友情链接
查看>>
将CDM中所有以Relatonship_开头的关系全部重命名,避免生成数据库因为重复关系名报错...
查看>>
C++ 标准库之algorithm
查看>>
系统限制和选项limit(一)
查看>>
Boson 6.0 试验笔记一
查看>>
隐藏滚动条 但是可以滚动
查看>>