博客前臺重構完畢了,接下來就是後臺部分了,後臺的主要功能就是發佈、刪除、修改文章,天然不是誰都能隨便進的。在 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