1.JWT用于登录身份验证
2.用户登录成功后,后端通过JWT机制生成一个token,返回给客户端
3.客户端后续的每次请求都需要携带token,放在header的authorization中
4.后端从authorization中拿到token后,通过secretKey进行解密验证省份
JWT生成的Token由三部分组成:header.payload.signature
**header:**主要是声明采用的加密算法
alg:指定生成signature采用的加密算法,默认是HS256
typ:令牌类型,jwt
**payload:**载荷,消息体,这里存放实际的内容
exp:设置过期时间
uid:用户uid
除了设置过期时间和用户的uid,还可以添加自定义私有字段,使用base64url进行编码组成JWT的第二部分
signature:
Signature = HMACSHA256(base64Url(header)+.+base64Url(payload),secretKey)
优点:
缺点:
cookie
的domain
属性设置为当前域的父域,并且父域的cookie
会被子域所共享。path
属性默认为web
应用的上下文路径
利用 Cookie
的这个特点,没错,我们只需要将Cookie
的domain
属性设置为父域的域名(主域名),同时将 Cookie
的path
属性设置为根路径,将 Session ID
(或 Token
)保存到父域中。这样所有的子域应用就都可以访问到这个Cookie
不过这要求应用系统的域名需建立在一个共同的主域名之下,如 tieba.baidu.com
和 map.baidu.com
,它们都建立在 baidu.com
这个主域名之下,那么它们就可以通过这种方式来实现单点登录
单点登录完全用前端来实现,前端拿到Token之后,前端通过 iframe
+postMessage()
方式,将同一份 Token
写入到了多个域下的 LocalStorage
中,前端每次在向后端发送请求之前,都会主动从 LocalStorage
中读取Token
并在请求中携带,这样就实现了同一份Token
被多个域所共享;此种实现方式完全由前端控制,几乎不需要后端参与,同样支持跨域
// 获取 token
var token = result.data.token;
// 动态创建一个不可见的iframe,在iframe中加载一个跨域HTML
var iframe = document.createElement("iframe");
iframe.src = "http://app1.com/localstorage.html";
document.body.append(iframe);
// 使用postMessage()方法将token传递给iframe
setTimeout(function () {
iframe.contentWindow.postMessage(token, "http://app1.com");
}, 4000);
setTimeout(function () {
iframe.remove();
}, 6000);
// 在这个iframe所加载的HTML中绑定一个事件监听器,当事件被触发时,把接收到的token数据写入localStorage
window.addEventListener('message', function (event) {
localStorage.setItem('token', event.data)
}, false);
当用户首次访问时,需要在认证中心登录:
1.当用户访问网站a.com下面的pageA页面,
2.由于没有登录,则系统A会返回给浏览器302重定向,并带上回调地址 www.sso.com?return_uri=a.com/pageA
,以便登录后直接进入对应页面。
3.重定向302之后,浏览器去访问重定向地址,认证中心验证未登录,则展示form,提示用户登录
4.用户在认证中心输入账号密码,提交登录
5.认证中心验证账号密码有效,然后重定向 a.com?ticket=123
带上授权码 ticket
,并将认证中心 sso.com
的登录态写入 Cookie
6.在 a.com
服务器中,拿着 ticket
向认证中心确认,授权码 ticket
真实有效。
7.验证成功后,服务器将登录信息写入 Cookie
(此时客户端有 2 个 Cookie
分别存有 a.com
和 sso.com
的登录态)
前端常见登录实现方案 + 单点登录方案 - 掘金 (juejin.cn)