流程大体以下:html
session会话保存到redis集群中,实现服务器共享session。前端
D:\redis
requirepass ****
,以下图:redis-server.exe
使用本地配置启动redisnode
cd D:\redis redis-server.exe redis.windows.conf
运行redis-cli.exe
以链接到您的redis实例react
cd D:\redis redis-cli.exe
PS:若是报了(error) NOAUTH Authentication required.是由于设置了认证密码,须要输入密码(就是上面设置的密码)进行认证登入jquery
Redis React是一个简单易用的用户界面,用于浏览Redis服务器中的数据,该数据由React桌面模板构建,可在Windows,OSX,Linux等多种平台上使用,也能够部署为自托管控制台或ASP.NET Web应用程序。git
Redis React充分利用了基于Web的UI的导航和深层连接优点,React框架的生产力和响应能力 以及本机桌面应用程序提供的丰富的本机体验和OS集成。github
下载链接:https://github.com/ServiceStackApps/RedisReact/raw/master/dist/RedisReact-winforms.exe,下载完直接执行便可ajax
在本地启动redis就能够轻松的模拟redis集群,全部其余服务器直接链接redis就能够了redis
本文后台使用nodeJs实现,生成session和操做redis依赖express-session
、connect-redis
、redis
三个库。sql
express-session
:中间件,用于在后端生成sessionID和cookie,会在request流对象中生成一个Session对象,用于操做session。connect-redis
:这是一个关于session的持久化插件, 配合express-session
使用。此模块基于redis,将session相关信息持久化(意思就是将session存入redis)。redis
:用于链接和操做redis数据库。
使用方式大体以下:
const express = require("express") const session = require('express-session') const RedisStrore = require('connect-redis')(session) const redis = require('redis') const config={ "cookie" : { "path": "/", "maxAge" : 1800000, "httpOnly": true }, "sessionStore" : { "host": "127.0.0.1", // redis主机 "port": "6379", // redis默认端口号 "pass": "****", "auth_pass": "****", // 设置了密码时须要该字段 } } const app = express() const client = redis.createClient(6379, '127.0.0.1', config.sessionStore) // 链接redis,建立实例 app.use(session({ name : "sessionId", // sessionID的属性名 secret : 'Asecret123-', // 生成sessionID的密钥 resave : false, rolling: false, //在每次请求时强行设置 cookie,这将重置 cookie 过时时间(默认:false) saveUninitialized : false, // 强制将未初始化的 session 存储。当新建了一个 session 且未设定属性或值时,它就处于未初始化状态。在设定一个 cookie 前,这对于登录验证,减轻服务端存储压力,权限控制是有帮助的。(默 认:true)。建议手动添加。 cookie: config.cookie, store: new RedisStrore({ client }) }));
使用后request流对象会新增sessionID字段和session对象
前端部分:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script> </head> <body> <div id="app">home</div> <button onclick="logout()">退出</button> </body> </html> <script> $.ajax({ url: "http://127.0.0.1:1001/getData", method: 'GET', dataType: 'json', xhrFields: { withCredentials: true //容许携带Cookie }, success: function(res) { console.log(res) if (res.code === 401) { window.location.href = "http://127.0.0.1:2000/?redirect_url=" + encodeURIComponent(window.location.href) } else if (res.code === 200) { $("#app").text(res.data.msg) } } }) function logout() { $.ajax({ url: "http://127.0.0.1:1001/logout", method: 'GET', dataType: 'json', xhrFields: { withCredentials: true //容许携带Cookie }, success: function(res) { if (res.code === 200) { // 不能再这里操做document.cookie来删除sessionId,由于设置了httpOnly window.location.reload() } } }) } </script>
后端部分:
// 拦截器 app.all('*', function(req, res, next) { if (req.cookies.sessionId) { var sessionId = req.cookies.sessionId.split('.')[0].replace("s:", "sess:") console.log('sessionId', sessionId) client.get(sessionId, function(err, reply) { console.log('reply', reply) if (reply) { next(); } }) } else { console.log("=============重定向到SSO=============") res.json({ code: 401 }) } }) app.get('/getData', (req, res) => { res.json({ code: 200, data: { msg: 'hello, welcome you!' } }) }) app.get('/logout', (req, res) => { req.session.destroy(err => { if (err) throw new ErrorEvent("注销失败") res.clearCookie("sessionId").json({ code: 200 }) }) })
初始进入页面发送http://127.0.0.1:1001/getData请求,若是没有携带cookie,后台拦截器就会拦截,返回401,前台判断是401就重定向到SSO
前端部分:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>login</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script> </head> <body> <div> <label>帐户:</label> <input type="text" class="account" name="account" value=""> </div> <div> <label>密码:</label> <input type="text" class="password" name="password" value=""> </div> <div> <input type="button" onclick="submit()" value="登陆"> <input type="reset" value="重置"> </div> </body> </html> <script> // 获取url参数 function getQueryVariable(variable) { var query = window.location.search.substring(1); var vars = query.split("&"); for (var i=0;i<vars.length;i++) { var pair = vars[i].split("="); if(pair[0] == variable){return pair[1];} } return(false); } function submit() { var account = $(".account").val().trim() var password = $(".password").val().trim() if (!account || !password) { alert("帐户密码不能为空") } $.ajax({ url: 'http://127.0.0.1:2001/login', method: 'POST', data: { account, password }, dataType: 'json', contentType: 'application/x-www-form-urlencoded', xhrFields: { withCredentials: true //容许携带Cookie }, success: function(res) { if (res.code === 200) { setTimeout(() => { window.location.href = decodeURIComponent(getQueryVariable("redirect_url")) }, 1000); } } }) } </script>
后台部分:
app.post('/login', (req, res) => { var account = req.body.account var pwd = req.body.password if (!account || !pwd) { console.log("帐户密码不能为空") return } nosql.one().make(builder => { builder.where('account', '=', account); builder.where('password', '=', pwd); builder.callback((err, userInfo) => { if (userInfo) { req.session.regenerate(err => { if (err) { console.log('生成sessionID失败: ' + err) } else { console.log(req) req.session.userInfo = userInfo req.session.save() // res.cookie("sessionId", req.sessionID, req.session.cookie) res.json({ code: 200 }) } }) } else { console.log("该帐户不存在") } }) }) })
这里数据库使用的是nosql文档数据库,依赖nosql
模块。登陆成功后regenerate方法会生成session和cookie,而后将session保存到redis中
PS:存在cookie中的sessionID和存在redis中的sessionID不同,这是由于express-session底层实现的缘由,有兴趣的同窗能够深刻一下
项目地址:https://github.com/Revelation...
https://segmentfault.com/a/11...
https://github.com/ServiceStackApps/RedisReact#download