单点登录前端实现

171 阅读2分钟

SSO(single sign on)单点登录、JWT鉴权

(1) jwt: JSON WEB令牌

使用json对象传输信息

形式(Base64-URL 字符串):xxxx(头部).yyyyyy(载荷).zzzzzzzz(签名);可在http环境传递

使用场景:

  • 授权:路由、资源、服务授权,单点登录
  • 信息交换:使用密钥对签名
组成部分
// header
{
  "alg": "HS256", // HMACSHA256  // 签名算法
  "typ": "JWT"  // 令牌类型
}
// payload, 包含一系列可读取的声明(claims)
// 信息做了防篡改处理但仍可读取,应避免加入机密信息
发行人、主题、受众等;用户信息,菜单、资源、数据等权限
{
  permissions: [],
  menus: [],
  userid: 'xxx',
  iss: 'xxx',  // 签发者
  exp: 124235332333   // 过期时间
  // ....
}
// 签名, 基于标头、载荷、算法、密钥计算; 用于验证消息是否被篡改
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
// 以vue接口权限、菜单权限为例
1. 接口权限
请求头携带token, axios做请求拦截处理

2. 菜单权限、按钮权限
(1) 将用户权限信息写入jwt声明中
(2) 登录校验成功后提取用户的权限信息,筛选可访问菜单等
(3) 注册全局自定义指令根据权限对菜单进行显隐藏处理

jwt相对swt、saml的优势:

  • 使用json对象传递信息,便于映射到js对象
  • 可使用密钥对进行签名
  • 编码后的字符串简洁短小,便于基于http进行传输

(2) 单点登录

快捷访问多个站点,实现多个系统间的用户身份信息交换;安全高效

JWT方案实现:

前端:存储token(localStorage), http重定向, jwt-decode, encodeURIComponent;

后端:使用redis集群存储登录信息

登入登出时序

  • 登入:根据请求头是否携带token判断登录状态 -> 若未登录则从业务系统跳转至单点登录站点,完成登录校验后,返回业务系统
  • 登出:服务端清除内存中的登录状态,客户端清除authToken
// 业务系统
1. token校验(是否存在,是否过期..),未通过调用toLoginPage
function toLoginPage() {
  localStorage.removeItem(TOKEN_KEY);
  const from = 'xxx';  // 当前项目地址
  window.location.href = `${门户网站地址}/#/login?from=${encodeURIComponent(from)}`;
}

// 门户网站
axios.post( // 登录处理 )
.then(() => {
    window.location.href = getQueryString('xxx');
})