单点登录sso及框架CAS介绍及引入node端

1、背景介绍

单点登录:Single Sign On,简称SSO,SSO使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
CAS框架:CAS(Central Authentication Service)是实现SSO单点登录的框架。

2、CAS介绍

网上搜的一张流程图:
CAS分为两部分,一个是CAS server,另一个是CAS client。
CAS client可以有多个,当用户需要访问受限(需要登录)url时,重定向到CAS server中进行登录。
CAS server是认证中心,用于多个网站登录,票据认证,传递用户信息等功能

3、CAS详细流程图及解释

4、CAS流程剖解分析

1、登录信息传递:

1.1用户首次登录A系统:
1)、用户访问A系统,A系统去浏览器拿登录状态id,发现未登录,然后拿票据,发现没有票据,需要重定向到用户中心。
2)、用户认证中心获取全局会话id,如若无,则去用户中心登录页登录。
3)、用户登录后,产生全局会话id和票据,然后重定向到系统A,并附上ticket票据。
4)、系统A从url获取票据信息,然后去用户中心验证票据是否有效
5)、用户中心验证票据有效,把用户信息传递给系统A,系统A再展示到用户浏览器中

1.2已登录用户首次访问系统B时:

1)、用户访问B系统,B系统去浏览器拿登录状态id,发现未登录,然后拿票据,发现没有票据,需要重定向到用户中心。
2)、用户认证中心获取全局会话id,存在,生成临时验证票据(验证之后就会失效)。
3)、认证中心发放临时票据(令牌),并携带该令牌重定向到系统B。
4)、系统B从url获取票据信息,然后去用户中心验证票据是否有效
5)、用户中心验证票据有效,把用户信息传递给系统B,系统B再展示到用户浏览器中

2、登录状态保持及判断(基于cookie或session):

1)、用户到CAS用户中心登录后,用户和认证中心之间建立起了全局会话。当继续访问改网站的时候,不可能每次都去用户中心验证登录状态,这样效率非常低下。
2)、于是就需要在系统和浏览器之间建立局部对话,如果局部对话存在,则用户为登录状态。局部会话依附于全局会话存在,全局会话消失,局部会话必须消失。
3)、用户访问应用时,首先判断局部会话是否存在,如存在,即认为是登录状态,无需再到认证中心去判断。如不存在,就重定向到认证中心判断全局会话是否存在,如存在,则通知该系统,该系统与客户端就建立起它们之间局部会话,下次请求该应用,就不去认证中心验证了。

3、登出

用户在一个系统登出了,在其他系统也应该是登出状态。所以在结束本地局部会话的同时需要通知用户中心用户通过该系统退出了。
用户中心接到该系统发出的登出请求之后,结束全局对话,同时通知所有子系统将他们的局部对话销毁,这样访问其他系统时也会使登出状态了。
整个流程如下:
1)、系统A发起logout请求
2)、系统A删除本地cookie或seesion,结束局部对话,同时通知用户中心
3)、系统A返回浏览器已登出
4)、认证中心通知所有子系统用户已登出。

5、node服务接入cas.server.com简易DEMO(基础egg)

5.1 接口详情

  async login() {//用户登录接口
    const { ctx } = this;
    let host = ctx.request.header.host
    ctx.response.redirect(`https://cas.server.com/cas/login?
    service=http://${host}/cas/validate`)
  }
  async logout() {//用户登出接口
    const { ctx } = this;
    let host = ctx.request.header.host
    ctx.session.userInfo = undefined;
    ctx.session.isLogin = undefined;
    ctx.response.redirect(`https://cas.server.com/cas/logout?
    service=http://${host}/cas/validate`)
  }
  async cas_logout() {//CAS服务器通知用户登出接口
    const { ctx } = this;
    ctx.session = null;
    ctx.body = '{"code":200,"data":"退出成功"}'
  }
  async validate() {//向CAS中心验证票据接口
    const { ctx } = this;
    let host = ctx.request.header.host
    let ticket = ctx.request.query.ticket
    let service = ctx.href.split('?')[0]
    if(ticket){
      let info = await request(`https://cas.server.com/cas/serviceValidate?
      service=${service}&ticket=${ticket}`)
      var _data = parseCasResponse(info.body)
      // console.log(_data)
      if(_data.code===200){//登录成功,去首页
        ctx.session.userInfo = _data.data
        ctx.session.isLogin = 1//登录状态保持
        ctx.cookies.set('ticket',ticket)
        ctx.response.redirect('/')
      }else{
        ctx.body = '票据丢失了哦!';
      }
    }else{
      if(ctx.session.user){//说明是无意进入这个链接,跳转到首页
        ctx.response.redirect('/')
      }else{
        ctx.response.redirect(`https://cas.server.com/cas/login?
        service=http://${host}/cas/validate`)
      }
    }
  }

5.2 中间件loginTest.js,部分路由如果未登录就要走登录接口

module.exports = options => {
    return async (ctx,next) => {
        let path = ctx.path
        if(
            path!=='/login' && path!=='/a' && path!=='/'
            && path!=='/logout' && path!=='/sso_logout' 
            && ctx.session.isLogin!==1
        ){
            ctx.response.redirect('/login')
        }
        await next()
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值