博客前台重构完毕了,接下来就是后台部分了,后台的主要功能就是发布、删除、修改文章,天然不是谁都能随便进的。在 vue 项目中,我是在 Vue Router 的全局前置守卫里判断当前用户是否有 cookie 从而判断是否有权进入后台。而 Nuxt 相比 Vue 项目最大的不一样之一就是没有使用 Vue Router 而是使用 目录来进行页面路由,天然咱们就失去了 全局前置守卫这个利器,固然 Nuxt 是有解决办的,不过在那以前咱们须要先来了解一下鉴权的原理。前端
相信前端的同窗们对这两个名字早就有所耳闻,却不必定有详细的了解。众所周知,咱们浏览网页使用的 HTTP 协议是无状态的的,也就是说你每一次请求对于服务器来讲都是同样的,它没有办法记住这个请求是你发的。因此这里就要用到Cookie。vue
Cookie 是服务端设置的,由浏览器储存在你的硬盘中的一组数据,,好比你的用户 数据,每次向服务器发送请求就会携带上这个数据。服务器查看就能知道这是谁发过来的。这一过程就称为Session(会话)mongodb
Session 初始是指一种概念,是你和网站发生交互的一个周期。在这个周期中服务器就是经过储存在浏览器的 Cookie 来判别你是谁。可是由于储存在本地的Cookie并不安全,谁均可以看到并更改,因此如今更为流行的作法是仅仅经过 Cookie 保存 的惟一的用户标识符(SessionID)来识别用户,而用户信息储存在服务器端。因此 Session 这个概念能够说是 Cookie 的上级也能够说是其同级数据库
讲解了 Nuxt 鉴权的基本原理,咱们能够知道鉴权就是在在用户进入这个页面的时候对本地的 Cookie 进行判断,存在设置好的 Cookie 那么说明这个用户已经登录过了,放他过去。啥也没有? 不行你去给我登录,就跳转到登陆页面。明白了这个流程就开始具体的工做了。npm
在服务器端咱们使用 koa-session 安装 koa-sessionpromise
npm install koa-session npm install koa-session-mongoose //使用 mongodb 储存 Session 信息
而后在入口文件中这样使用浏览器
app.use( session( { key: "***", //加密密钥 overwrite: true, //覆写Cookie httpOnly: true, //经容许经过 JS 来更改 renew: true, store: new MongooseStore({ createIndexes: "appSessions", connection: mongoose, expires: 86400, // 1 day is the default name: "AppSession" }) //传入一个用于session的外部储存,我这里是使用了 mongodb }, app ) );
由于 koa 默认会把 Session 打到 ctx.session
中,不方便用户端获取,因此咱们把它移一下位,挪到 ctx.req.session
中安全
app.use((ctx) => { ctx.status = 200 ctx.respond = false // Bypass Koa's built-in response handling ctx.req.session = ctx.session ctx.req.ctx = ctx // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash 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) }) }) })
这是登录函数,查询数据库是否又对应的用户名和密码,存在的话,给客户端设置一个 Cookie 返回登陆成功服务器
static async login(ctx) { let { passwd, email } = ctx.request.body; let hasuser = await UserModel.findOne({ email: email, passwd: md(passwd) }); if (!hasuser) { return ctx.error({}); } else { let userid = hasuser._id; const { session } = ctx; session.userid = userid; return ctx.success({ data: { userid: userid } }); } }
服务端设置完成了cookie
其实以上的步骤和 Vue 项目中如出一辙,Nuxt 中主要的不一样就是失去了全局前置守卫,那么要在哪里判断是否存在 Cookie 呢,别急,Nuxt 官方天然是给了解决方案,先看一下 Nuxt 的生命周期
这里咱们用到的就是红框中的 nuxtServerInit
和 middleware
这两个时期,先来看代码
// store/index.js Vuex 文件中 export const actions = { // nuxtServerInit is called by Nuxt.js before server-rendering every page nuxtServerInit({ commit }, { req }) { if (req.session && req.session.userid) { console.log("用户已经登陆"); commit("SET_USER", req.session.userid); } }, export const mutations = { SET_USER(state, user) { state.authUser = user; }, }
Store action 模块中的 nuxtServerInit 函数是整个生命周期 最早运行的,咱们就在这里判断当前用户浏览器中是否有 Cookie ,若是有的话就在 state 中用一个字段保存下来。是否是还挺像全局前置守卫。这里还只是作了判断,打上了印记你登没登录,拦截在哪里呢,别急,就是下一个流程 middleware
中。
打开 middleware 文件夹( Nuxt 项目自带),新建 auth.js 文件
// auth.js export default function ({ store, redirect }) { if (!store.state.authUser) { return redirect('/welcome') } }
瞧一下 Vuex 中看看你有没有登录,没有的话把你送到登录页面去,简单直接吧,只要在须要鉴权的页面引用这个中间件便可,对于此项目只要在后台管理页面引用就好
export default { middleware: 'auth', };
就这样完成了鉴权的操做,没有登录过的用户在访问后台是时候会被重定向到登录页面去,就是很简单的使用了一下 Cookie ,限于项目性质,session 的不少功能并无用到,好比在服务器端储存用户信息。主要是它的功能也就是防止别人访问后台,很是简单。
还会有后续文章
敬请期待
Welcome to my Blog