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');
})