正在加载中,请稍后

Token+JWT

Token+JWT,Oauth2

什么是单点登录:

用户只要一次登录,就可以访问所有互相信任的应用服务。

JWT结构

Header:头信息,利用Base64Url编码存储token类型和加密算法。

有效负载:存储了一些我们需要的信息,例如用户名,用户id等。

签名:使用header中存储的加密算法和定义的秘钥生成签名。

1.Jwt和Spring Security的对比:

JWT的

优点

无需在服务端存储用户数据,减轻服务端压力
轻量级,json风格,比较简单
跨语言
有利于水平扩展
缺点:

token一旦签发,无法修改
无法更新token有效期,用户登录状态刷新难以实现
无法销毁一个token,服务端不能对用户状态进行绝对控制
不包含权限控制
SpringSecurity:

优点:
用户信息保存再服务端,服务端可以对用户状态绝对控制
基于Spring,无缝整合,修改登录逻辑,其实就是添加过滤器
整合权限管理
缺点:
限定了语言
实现复杂,基于一连串的过滤器链
需要再服务端保存用户信息,增加服务端压力
依赖于tomcat的HttpSession、如果是分布式项目,session不共享,登录失效,需要借助于SpringSession,实现共享session效果(利用redis代替tomcat的session)

2.登录控制问题

你们使用JWT做登录凭证,如何解决token注销问题

答:jwt的缺陷是token生成后无法修改,因此无法让token失效。只能采用其它方案来弥补,基本思路如下:

1)用户登录后,生成JWT,其中包含用户身份

2)以用户id为key,把JWT的id存入redis,只有redis中有id的JWT,才是有效的JWT

3)并且给Redis设置有效期,有效期到自动删除

4)退出登录时,把ID从Redis删除即可

怎么解决登录超时后的登录续签问题?

答:判断登录是否超时的标准是redis,而不是JWT,因此每次用户访问网关,我们都会刷新redis的数据有效期,保证登录状态不断。

如何解决异地登录或跨设备登录问题?

答:

方案一:不允许多端登录

如果账户在第二个设备登录,自然会将redis中的JWT覆盖,那么之前的登录凭证就成了无效凭证。

方案二:允许多端登录

存入redis时,redis的类型可以选择set,这样一个用户可以具备多个JWT的id,实现多端登录。

3.cookie安全问题

JWT中的cookie泄露,是否会泄露用户隐私?

不会,因为JWT中只保存用户id这样的非敏感字段,不存放例如手机、用户名、密码之类的信息
如何解决token被篡改问题?

答:token中的数据可以篡改,但是签名无法篡改,否则服务端认证根本不会通过,因此篡改的token是无法通过服务端校验的
如何防止token的伪造

与上个问题类似,token中带有签名认证,而签名需要秘钥加密生成。只要秘钥不泄露,就不可能有人伪造token,因为其它秘钥生成的token是不会被认可的。
另外,我们服务内部有秘钥管理机制,其它外部请求是无法获取我们的秘钥的。
如何解决cookie被盗用问题?

答:cookie被盗用的可能性主要包括下面几种:

XSS攻击:这个可以再前端页面渲染时对 数据做安全处理即可,而且我们的cookie使用了Httponly为true,可以防止JS脚本的攻击。
CSRF攻击:
利用Referer头,防盗链
请求头中加随机码
数据抓包,获取用户cookie:我们采用了HTTPS协议通信,无法获取请求的任何数据
请求重放攻击:对于普通用户的请求没有对请求重放做防御,而是对部分业务做好了幂等处理。运行管理系统中会对token添加随机码,认证token一次有效,来预防请求重放攻击。
用户电脑中毒:这个无法防范。
用户的cookie被禁用怎么办?

cookie一般情况下,是不会被禁用,因为普通人根本不知道是什么是cookie,一般不用管,为了友好,我们可以给用户一个提示:你的cookie已经被禁用了,请启用cookie。
把jwt作为响应头返回,浏览器中JS把token写到本地存储(sessionStorage),要求前端每次发ajax,都必须自己携带token。而且有被xss攻击的风险

4.权限问题

如何完成权限校验的?

首先我们有权限管理的服务,管理用户的各种权限,及可访问路径等
在网关中利用过滤器,拦截一切请求,在过滤器中,解析和验证jwt,获取用户身份,查询用户权限,判断用户身份可以访问当前路径

原文链接:https://blog.csdn.net/weixin_51291483/article/details/109211659

解决跨域:

原理:让token在多个域中共享,因为浏览器对cookie的限制越来越严格,无法在多个域中共享cookie。在前后端分离的情况下,完全可以不使用 Cookie,我们可以选择将 Session ID (或 Token )保存到浏览器的 LocalStorage 中,让前端在每次向后端发送请求时,主动将 LocalStorage 的数据传递给服务端。

做法:

前端通过 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);

Spring-Security-oauth2

OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。
链接:https://www.jianshu.com/p/84a4b4a1e833

image

posted @ 2021-05-17 09:34  wode虎纹猫  阅读(372)  评论(0)    收藏  举报
Live2D