认证与授权:二、session认证

1、session认证原理


认证与授权:二、session认证_第1张图片

流程大致如下:

  • 进入某个平台的页面后会发送一些请求,第一次请求时没有携带cookie,自动条状到SSO进行登录
  • 登陆后,SSO会生成sessionID并保存到cookie中,然后重定向到应用平台
  • 接着发送的请求会携带cookie,如果session过期,那么跳转到SSO再一次登录

2、window下redis安装与使用


session会话保存到redis集群中,实现服务器共享session。

2.1、安装redis

  • 使用wget或者直接到github下载redis压缩包,将压缩包解压到任何文件夹中,比如D:\redis
  • 设置密码,打开redis.windows.conf文件,添加requirepass ****,如下图:
  • redis-server.exe使用本地配置启动redis

    cd D:\redis
    
    redis-server.exe redis.windows.conf
  • 运行redis-cli.exe以连接到您的redis实例

    cd D:\redis
    
    redis-cli.exe
  • 开始使用redis

PS:如果报了(error) NOAUTH Authentication required.是因为设置了认证密码,需要输入密码(就是上面设置的密码)进行认证登入

2.2、使用图形化工具连接redis

Redis React是一个简单易用的用户界面,用于浏览Redis服务器中的数据,该数据由React桌面模板构建,可在Windows,OSX,Linux等多种平台上使用,也可以部署为自托管控制台或ASP.NET Web应用程序。

Redis React充分利用了基于Web的UI的导航和深层链接优势,React框架的生产力和响应能力 以及本机桌面应用程序提供的丰富的本机体验和OS集成。

3、模拟redis集群

在本地启动redis就可以轻松的模拟redis集群,所有其他服务器直接连接redis就可以了

本文后台使用nodeJs实现,生成session和操作redis依赖express-sessionconnect-redisredis三个库。

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对象

认证与授权:二、session认证_第2张图片

3、应用平台实现


前端部分:




  
  
  Document
  


  
home

后端部分:

// 拦截器
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

4、SSO实现


前端部分:




  
  
  login
  


    

后台部分:

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...

5、参考

https://segmentfault.com/a/11...
https://github.com/ServiceStackApps/RedisReact#download

https://github.com/ServiceStack/redis-windows

你可能感兴趣的:(session,认证授权)