*參考koa-session源碼html
1.第一次向服務器發送請求時在服務器端建立Session對象,該對象有一個惟一的IDjava
2.在建立Session對象的同時會建立一個特殊的Cookie對象,該Cookie對象的名字是一個固定值JSESSIONID,該對象的值就是Session對象的ID值,同時會將這個特殊的Cookie對象發送給瀏覽器.mysql
3.之後瀏覽器在發送就會攜帶這個特殊的Cookie對象git
4.服務器獲取JESSIONID的這個Cookie對象的value以後,在服務器中查找與之想對應的Session對象,來區分不一樣的用戶github
session對象的獲取 :HttpSession session = request.getSession()redis
能夠用以下的代碼證實:sql
package xdp.gacl.session;數據庫
import java.io.IOException; import javax.servlet.ServletException;apache
import javax.servlet.http.HttpServlet;npm
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF=8"); response.setContentType("text/html;charset=UTF-8"); //使用request對象的getSession()獲取session,若是session不存在則建立一個 HttpSession session = request.getSession(); //將數據存儲到session中 session.setAttribute("data", "是個麻瓜"); //獲取session的Id String sessionId = session.getId(); //判斷session是否是新建立的 if (session.isNew()) { response.getWriter().print("session建立成功,session的id是:"+sessionId); }else { response.getWriter().print("服務器已經存在該session了,session的id是:"+sessionId); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } 複製代碼
}
服務端:
對象序列化
的技術來實現的:當須要從新加載Session對象時(如服務器再次啓動的時候),經過對象反序列化
的技術在內存中從新構造Session對象。Tomcat
經過Session Manager來建立和維護HTTP Session,當你沒有配置其它的Session Manager實現時,默認使用StandardManager類。StandardManager在Tomcat服務器正常關閉、重啓或者Web應用程序中止時,將內存中的全部活動的HttpSession對象序列化到硬盤文件中;當Web應用程序從新開始運行時,發序列化HttpSession對象,在內存中從新構建HttpSession對象,以及HttpSession中保存的全部對象(假定HttpSession對象沒有過時)。這種方式須要安裝koa-session-minimal和koa-mysql-session兩個依賴。 執行
npm install koa-session-minimal koa-mysql-session --save 項目配置:
const session = require('koa-session-minimal');
const MysqlStore = require('koa-mysql-session');
const config = require('./config/default.js'); // 數據庫配置
const Koa = require('koa');
const app = new Koa();
// session存儲配置 const sessionMysqlConfig = { user: config.database.USERNAME, password: config.database.PASSWORD, database: config.database.DATABASE, host: config.database.HOST, };
// 配置session中間件 app.use(session({ key: 'USER_SID', store: new MysqlStore(sessionMysqlConfig) }));
這種方式會自動在數據庫創建一個表 在瀏覽器的cookie中會生成一個以 USER_SID 爲鍵的cookie。經過ctx的session屬性能夠修改更新刪除session的值。 缺點
是每次對session的操做須要查詢數據庫,比較耗時。
主要用到了koa-session2和ioredis。 執行
npm install koa-session2 ioredis --save 具體實現代碼參考下面的
項目實踐與測試
部分
每次登錄能夠經過Redis來存儲會話信息,因爲Redis直接是運行在內存中的,所以速度會比較快。 經過get key 便可查看相應的session信息。
Redis是一款開源的、高性能的鍵-值存儲(key-value store)。它常被稱做是一款數據結構服務器(data structure server)。
Redis集羣~windows下搭建Sentinel環境及它對主從模式的實際意義:
使用ioredis存儲session的具體步驟: 參考ioredis的接口文檔,提供sentinel環境redis的存儲
在管理系統項目中實現redis對session的存儲,其中,redis爲哨兵模式集羣
redis: {
//哨兵部署 sentinels: [ { host: '127.0.0.1', port: 26379 },{ host: '127.0.0.1', port: 26380 }, { host: '127.0.0.1', port: 26381 } ], //加這個才能夠找到主服務器 name:"mymaster", } 複製代碼
const Store = require('./app/redis/redis-store');
app.use(session({
store:new Store(config.redis),
maxAge: 86400000 }))
//redis處理session持久化
app.use(require('./app/interceptors/redis-session'))
'use strict'; const config = require('config');
module.exports=async (ctx,next)=>{
ctx.destroySession=function () {
var self = this; // console.log("destroySession") if(self.session){ self.session=undefined; // console.log("shanchu") return true; }else{ return false; } 複製代碼
}; await next();
}
async function (ctx, next) { const self = this; try {
// 若是已經登陸,則直接返回 if (ctx.hasLogin()) { ctx.destroySession();//刪除session resp.success({ data: true }, ctx); } } catch (e) { resp.failed({ desc: e.toString() }, ctx); } finally { // 執行流程交給下一個middle-ware await next(); } 複製代碼
}
運行項目以前按照上述sentinel環境的搭建指南搭建環境,並在項目中安裝相關的庫後運行項目