在我們訪問一些網站內部內容的時候,通常都會先驗證我們是否已經登陸,如果登陸了就跳轉到內容頁面否則就跳轉或者彈出登陸頁面。
但是HTTP協議是沒有狀態的協議,無法標識一個用戶的登錄狀態。
於是Cookies和Session的應用就很好的解決了這個問題。
koa實現session登陸的方法很簡單,首先引入依賴'koa-session'
const session = require('koa-session');
配置session參數
//session配置 const session_signed_key = ["some secret hurr"]; // 這個是配合signed屬性的簽名key const sessionConfig = { key: 'koa:sess', //cookie key (default is koa:sess) maxAge: 1800000, // 過期時間(毫秒) maxAge in ms (default is 1 days) overwrite: true, //是否可以overwrite (默認default true) httpOnly: true, //cookie是否只有服務器端可以訪問 httpOnly or not (default true) signed: true, //簽名默認true rolling: false, //在每次請求時強行設置cookie,這將重置cookie過期時間(默認:false) renew: false, //(boolean) renew session when session is nearly expired, };
加載中間件(一定要注意中間件的加載順序)
app.keys = session_signed_key;
app.use(session(CONFIG, app));
登錄接口部分
/** * 登陸 * @author Shellcoochi * @param ctx * @param next * @returns {Promise<void>} */ let fn_sign_in = async (ctx, next) => { let name = ctx.request.body.username || '', password = ctx.request.body.password || ''; console.log(`signin with name: ${name}, password: ${password}`); if (name === 'Shellcoochi' && password === '12345') { //設置session ctx.session.userState = true; ctx.session.username = name; ctx.response.body = { state:'success', msg:'登陸成功' }; console.log('登陸成功'); } else { ctx.response.body = {state:'defeat'}; } };
設置session的同時我們也可以設置前端的Cookies
/** * 登陸 * @author Shellcoochi * @param ctx * @param next * @returns {Promise<void>} */ let fn_sign_in = async (ctx, next) => { let name = ctx.request.body.username || '', password = ctx.request.body.password || ''; console.log(`signin with name: ${name}, password: ${password}`); if (name === 'Shellcoochi' && password === '12345') { //設置session ctx.session.userState = true; ctx.session.username = name; //設置cookie ctx.cookies.set( 'shellcoochi@',//name 'mytoken@', //value(可替換為token) cookieConfig ); ctx.response.body = { state:'success', msg:'登陸成功' }; console.log('登陸成功'); } else { ctx.response.body = {state:'defeat'}; } };
Cookies相關配置
注:每一個域名都有自己對應的Cookies,如果兩個域名同屬於一個域名的二級域名
可以設置他們的domain為一級域名,這樣兩個二級域名都可以訪問到一級域名的Cookies,實現在一級域名相同的情況下的Cookies的“跨域”操作
//cookie配置 const cookieConfig = { domain: 'localhost', // 寫cookie所在的域名 path: '/', // 寫cookie所在的路徑 maxAge: 1800000, // cookie有效時長 // expires: new Date('2017-02-15'), // cookie失效時間 httpOnly: false, // 是否只用於http請求中獲取 overwrite: false // 是否允許重寫 }
如果當前用戶處於登錄狀態許訪問后台接口,或者正在訪問不需要登陸就可以訪問的接口,則允許通過,否則不允許訪問。
我們可以在一個訪問進入路由前加一個簡單的攔截器
const allowpage = ['/node/signin']//允許直接訪問的接口 module.exports = function(ctx, next){ let url = ctx.originalUrl; if(allowpage.indexOf(url)>-1){ console.log("正在登陸。。。"); }else if(ctx.session.userState){ console.log("正在訪問接口:"+url); }else{ console.log("session 已失效,請重新登錄"); ctx.redirect(null); } };
刪除session
/** * 登出 * @author Shellcoochi * @param ctx * @param next * @returns {Promise<void>} */ let fn_sign_out = async (ctx,next)=>{ if(ctx.session){ ctx.session =null;//清空session ctx.response.body = { state:'success', msg:'登出成功' } console.log('登出成功') }else{ ctx.response.body = { state:'defeat', msg:'session 已失效' } console.log("當前 session 已失效"); } };