1
psnnf 2021-11-23 18:02:58 +08:00
JWT 加个全局拦截器
|
2
mgcnrx11 2021-11-23 18:11:23 +08:00 3
千万别在没想清楚的时候用 JWT [手动狗头
|
3
xuanbg 2021-11-23 18:16:13 +08:00 1
不推荐 JWT ,更不推荐 Spring Security 。自己造个轮子简单实用。
|
4
huxiaofan1223 2021-11-23 21:27:51 +08:00 via iPhone
@mgcnrx11 为啥呢
|
5
kytrun 2021-11-23 21:32:40 +08:00 via Android 1
推荐 sa-token
|
6
LeeReamond 2021-11-23 21:38:55 +08:00 6
@huxiaofan1223 jwt 只能应对它的初始设计场景,也就是令牌签发后有效期内一直有效。如果你有后续的需求,比如用户的令牌丢了,或者用户想要改密码,要让已签发的令牌失效,那么 jwt 就不能做到,需要在 jwt 基础上再加补丁。而补丁的实现,由于把存在性校验换成了不存在性校验,算法上确实可以做到一定的优化,但这种优化往往只有在特大数据量下才能表现出实际差距,考虑到开发成本,这未必值当。对于没想清楚需求的应用来说,直接保存 sessionid 是最直接也最方便的做法。
|
7
huxiaofan1223 2021-11-23 21:41:28 +08:00 via iPhone
@LeeReamond 用 redis 和拦截器可以解决你说的这个吗?
|
8
huxiaofan1223 2021-11-23 21:42:58 +08:00 via iPhone
@LeeReamond cookie 和 session 方便是方便,问题是对客户端不友好吧(我是前端,这是我的猜测)
|
10
clf 2021-11-24 00:34:17 +08:00 via iPhone
sa token 挺好的。登录的 token 别用 jwt ,不然 token 自动续签会很麻烦。
|
12
jinliming2 2021-11-24 01:07:51 +08:00
@huxiaofan1223 客户端问题也不大,正常的网络请求库都有 cookie jar ,自动管理 cookie 的
|
13
chendy 2021-11-24 08:25:34 +08:00
一个 ThreadLocal 存当前用户(和权限) + 一个拦截器存进去+删掉,完事
可以参考安全框架的设计,但是不建议用,因为麻烦。。。 |
14
JamesMackerel 2021-11-24 09:00:28 +08:00 via iPhone
一个服务:数据库里存密码,用 bcrypt 存储密码。
多个服务:用 sso ,可以用 oauth 或者 cas 。 登录验证的 filter 可以抄一下 java-cas-client 里的 AuthenticationFilter ,获取当前用户信息的操作可以抄 AssertionHolder |
15
banlifeather4 2021-11-24 09:10:13 +08:00
@LeeReamond
1. 用户令牌丢了? 回答:这个问题.... 2. 用户改密码后,使已签发的令牌失效 回答:用户密码后,可以再生成新的 token , 你可以选择返回前端, 让他更新请求令牌,或让用户重新登录(取决于你的需求设计) |
16
sujin190 2021-11-24 09:14:19 +08:00
@banlifeather4 #15 我猜改密码这个的意思是用户登录了两台设备,在其中一台设备上改密码了,无法把另外一台踢下线,否则就得查询用户状态了,这样还不如用 session 了
|
17
sujin190 2021-11-24 09:16:17 +08:00
@huxiaofan1223 #8 因为好多不知道 cookiejar 的,所以各种传 cookie 和 session 对客户端不友好也真是。。
|
18
banlifeather4 2021-11-24 09:20:57 +08:00
|
19
masterclock 2021-11-24 09:22:03 +08:00
1. 不登录
2. 用 Keycloak 之类的东西,总之保证请求到自己的服务的时候,鉴权啥的都已经完成了,不需要关心了 |
20
LeeReamond 2021-11-24 09:22:44 +08:00
@banlifeather4 很正常的需求,不知道你想问什么,比如手机作为唯一身份认证终端的时代 ,丢手机当然不是 0 概率事件,其他认证方式同理,你这问题属于想的太多做得太少,做了就遇到这种需求了。
|
21
sujin190 2021-11-24 09:30:24 +08:00
@banlifeather4 #18 你这个并没有解决问题吧,且不说最简单的设备不在线就走不通,毕竟不是大厂设备在线率不能比,再者用户改密码大多可能有异常登录之类的,既然异常登录了,那说不定 WS 就没用了呢,所以你这个方案是无所谓的正常改密码能正常踢下线,必须要改密码的异常情况恰恰可能反而踢不下线了,反着来么
|
22
mosakashaka 2021-11-24 09:34:47 +08:00 1
jwt 踢用户做点改造不就得了,加个自定义属性。
spring security 没明白为什么不用,而要自己造轮子。。 |
23
securityCoding 2021-11-24 09:48:44 +08:00
登录态拦截在网关做,业务中从上下文获取属性即可根本不要关注登录态.省时省力省心
|
24
timethinker 2021-11-24 10:03:28 +08:00 7
登录其实就是认证,认证与授权是两个相对独立的过程。
认证解决的问题:你是谁?一般只是简单的通过标识(用户名)和凭证(密码)来确定身份。确定身份以后,认证系统一般会发放一个 Token (令牌)或者直接绑定身份信息并关联当前的 sessionid (会话,通过 cookie 传递)。 授权解决的问题:在已认证的情况下,也就是我知道你是谁的情况下,你能做什么? 关于密码:不要使用明文,后端也不要接收明文(固然有 TLS ),前端可以使用 BCrypt 慢哈希生成密码摘要,不要在后端使用慢哈希。后端生成(注册)/获取(登录)动态盐值,与前端发过来的摘要结合再次哈希一遍得到最终的摘要信息。 关于 JWT:JWT 只是作为令牌的一种承载形式,它不可伪造,不可篡改,表达了签发此令牌的真实意图,但是不要将敏感信息放进去。好处固然有,例如完全可以在不跟签发者通讯的情况下对其进行验证(签名以及有效期),但是涉及到撤销的情况下,就必须记录每一个令牌的状态( jti 是每一个令牌的 ID ),可以建立令牌黑名单机制,虽然丧失了完全的无状态好处,但是验证这个比较轻量级。 我想说的就是可以根据场景结合混合使用不同的技术,关于安全这一块,不要自己去发明东西,大胆的使用经过时间检验的通用方法,具体如何实现只是细节问题(比如框架,亦或是自己手写),但是在流程上,概念上一定要有清晰的认知。 |
25
shuimugan 2021-11-24 13:08:00 +08:00 via Android
如果项目前后端分离得很彻底,可以把原来存在 cookie 的 session id 丢到 local storage ,请求的时候取出来追加到 header 上,可以从根本上杜绝 csrf 攻击,还能让扫描器或者等保服务提供商的初级安全人员一脸懵逼
|
26
Casbin 2021-11-24 13:12:27 +08:00
可以试试 Casdoor: https://v2ex.com/t/803669 ,支持与 Spring-Boot 项目集成: https://github.com/casdoor/casdoor-spring-boot-example
|
27
ihwbunny 2021-11-24 13:17:42 +08:00
为啥没人提多设备验证
|
28
danieladu 2021-11-24 16:06:09 +08:00
无非就是
[OAuth 2.0]( https://oauth.net/2/), [OpenID]( https://auth0.com/docs/authorization/protocols/openid-connect-protocol#openid-and-jwts), [JWT]( https://jwt.io/) 还有比较新的: [Auth0]( https://auth0.com/) [webAuthn]( https://www.w3.org/TR/webauthn-2/) 当然还有一些大厂的库: [google Identity Platform]( https://cloud.google.com/identity-platform) [Firebase Authentication]( https://firebase.google.com/docs/auth/) [Azure AD]( https://azure.microsoft.com/en-us/services/active-directory/) 国内的第三方登录库 [justAuth]( https://github.com/justauth/JustAuth) 附上 [Authentication 和 Authorization 的别]( https://auth0.com/docs/get-started/authentication-and-authorization#what-are-authentication-and-authorization-) |
29
yangzzzzzz 2021-11-24 16:18:05 +08:00
简单点 jwt 单 token ,复杂点双 token 。
|
30
MonikaCeng 2021-11-24 17:31:46 +08:00 via Android
我之前做短信登录,安全策略是,同 ip 发短信超过 5 条该 ip 需要验证码。当日短信发送总量超过 1000 条,当日所有人需要验证码
|
31
getoffworkontime 2021-11-24 19:04:04 +08:00
直接用阿里云的 API 网关
|
32
leeg810312 2021-11-24 23:11:45 +08:00 via Android
jwt 那么多好处为什么不用? jwt 跨域方便,横向扩展方便,代码什么都不用改,cookie 和 session 可以吗? jwt 没有提供吊销,但也容易补这个特性。生成时缓存一份,校验前去缓存查一下,吊销时把缓存里的删了就好了。jwt 的好处也用了,缺点也弥补了。
|
33
joApioVVx4M4X6Rf 2021-11-25 09:49:28 +08:00
@yangzzzzzz 求教双 token 是啥啊?是 access_token 和 refresh_token 吗
|
34
ArmstrongLiu 2021-11-25 10:41:27 +08:00
@qwe520liao #24 关于“关于密码” 这块有两个疑问:
1. Bcrypt 哈希算法每次生成的哈希值都是不同的(即使是相同的密码),这样后端是如何校验密码的正确性的呢? 2. 前后端交互时不使用明文的原因是什么?如果出现别人通过抓包或者请求拦截获取到密码或者密码摘要,这二者造成的后果是不是都是一样的?因为不管是用密码或者是密码摘要模拟请求,后端的密码验证都是可以通过的。 |
35
timethinker 2021-11-25 13:03:36 +08:00
@ArmstrongLiu
1 、前端 Bcrypt 是可能的,我们需要的就是把“慢”这个过程放到客户端内,代码细节可以看一下我刚创建的这个测试,需要一个固定的盐值: https://jsfiddle.net/4zdw1jab/ 2 、不使用明文不仅仅只是说为了传输上的考虑,明文就是“烫手山芋”,只要生成摘要的过程是安全可靠的,其实我们根本就不需要明文。其他的顾虑包括但不限于意外的日志输出或者其他的安全漏洞,所以彻底的做法就是后端根本就不接收明文。当然这一条只是作为一个建议,如果手动模拟注册请求给后端接口发送的就是明文,那么当然也可以模拟登录用之前的明文,关于这种“非法”注册的用户,当然也就排除在正常的产品流程之外了。 |
36
ZeroDu 2021-11-25 15:38:09 +08:00
自己写个拦截器 + uuid +redis 无烦恼。
|
37
yangzzzzzz 2021-11-25 16:09:18 +08:00
@v2exblog 是的
|
38
ArmstrongLiu 2021-11-26 11:05:15 +08:00
@qwe520liao 如果前端使用固定盐值,那应该没有问题。我之前使用 python ( passlib.hash )进行测试时一直没有使用盐值,所以它每次都自动生成 salt ,就导致每次的 hash 值不同。
|
39
letitbesqzr 2021-11-29 11:08:19 +08:00
sa-token 好用
|