登录最佳实践是什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
7911364440
V2EX    Java

登录最佳实践是什么?

  •  
  •   7911364440 2021 年 11 月 23 日 8770 次点击
    这是一个创建于 1615 天前的主题,其中的信息可能已经有所发展或是发生改变。
    39 条回复    2021-11-29 11:08:20 +08:00
    psnnf
        1
    psnnf  
       2021 年 11 月 23 日
    JWT 加个全局拦截器
    mgcnrx11
        2
    mgcnrx11  
       2021 年 11 月 23 日   3
    千万别在没想清楚的时候用 JWT [手动狗头
    xuanbg
        3
    xuanbg  
       2021 年 11 月 23 日   1
    不推荐 JWT ,更不推荐 Spring Security 。自己造个轮子简单实用。
    huxiaofan1223
        4
    huxiaofan1223  
       2021 年 11 月 23 日 via iPhone
    @mgcnrx11 为啥呢
    kytrun
        5
    kytrun  
       2021 年 11 月 23 日 via Android   1
    推荐 sa-token
    LeeReamond
        6
    LeeReamond  
       2021 年 11 月 23 日   6
    @huxiaofan1223 jwt 只能应对它的初始设计场景,也就是令牌签发后有效期内一直有效。如果你有后续的需求,比如用户的令牌丢了,或者用户想要改密码,要让已签发的令牌失效,那么 jwt 就不能做到,需要在 jwt 基础上再加补丁。而补丁的实现,由于把存在性校验换成了不存在性校验,算法上确实可以做到一定的优化,但这种优化往往只有在特大数据量下才能表现出实际差距,考虑到开发成本,这未必值当。对于没想清楚需求的应用来说,直接保存 sessionid 是最直接也最方便的做法。
    huxiaofan1223
        7
    huxiaofan1223  
       2021 年 11 月 23 日 via iPhone
    @LeeReamond 用 redis 和拦截器可以解决你说的这个吗?
    huxiaofan1223
        8
    huxiaofan1223  
       2021 年 11 月 23 日 via iPhone
    @LeeReamond cookie 和 session 方便是方便,问题是对客户端不友好吧(我是前端,这是我的猜测)
    vance123
        9
    vance123  
       2021 年 11 月 24 日
    交给第三方处理(大雾)
    当初本着能外包则外包的原则,选了 auth0.com 做用户管理,结果要学的东西更多了
    clf
        10
    clf  
       2021 年 11 月 24 日 via iPhone
    sa token 挺好的。登录的 token 别用 jwt ,不然 token 自动续签会很麻烦。
    gargar
        11
    gargar  
       2021 年 11 月 24 日
    @vance123 哈哈,跟上云一样,以为不用自己维护机房了,结果要学的东西一点都不少
    jinliming2
        12
    jinliming2  
       2021 年 11 月 24 日
    @huxiaofan1223 客户端问题也不大,正常的网络请求库都有 cookie jar ,自动管理 cookie 的
    chendy
        13
    chendy  
       2021 年 11 月 24 日
    一个 ThreadLocal 存当前用户(和权限) + 一个拦截器存进去+删掉,完事
    可以参考安全框架的设计,但是不建议用,因为麻烦。。。
    JamesMackerel
        14
    JamesMackerel  
       2021 年 11 月 24 日 via iPhone
    一个服务:数据库里存密码,用 bcrypt 存储密码。
    多个服务:用 sso ,可以用 oauth 或者 cas 。

    登录验证的 filter 可以抄一下 java-cas-client 里的 AuthenticationFilter ,获取当前用户信息的操作可以抄 AssertionHolder
    banlifeather4
        15
    banlifeather4  
       2021 年 11 月 24 日
    @LeeReamond

    1. 用户令牌丢了?
    回答:这个问题....


    2. 用户改密码后,使已签发的令牌失效
    回答:用户密码后,可以再生成新的 token , 你可以选择返回前端, 让他更新请求令牌,或让用户重新登录(取决于你的需求设计)
    sujin190
        16
    sujin190  
       2021 年 11 月 24 日
    @banlifeather4 #15 我猜改密码这个的意思是用户登录了两台设备,在其中一台设备上改密码了,无法把另外一台踢下线,否则就得查询用户状态了,这样还不如用 session 了
    sujin190
        17
    sujin190  
       2021 年 11 月 24 日
    @huxiaofan1223 #8 因为好多不知道 cookiejar 的,所以各种传 cookie 和 session 对客户端不友好也真是。。
    banlifeather4
        18
    banlifeather4  
       2021 年 11 月 24 日
    @sujin190

    EMMM , 我们有用到 WS , 所以一些关键流程, 会推送消息到前端, 让前端处理一些流程;
    就像我们使用大厂的 APP 一样, 会弹出来, 密码已修改,需要重新登录
    masterclock
        19
    masterclock  
       2021 年 11 月 24 日
    1. 不登录
    2. 用 Keycloak 之类的东西,总之保证请求到自己的服务的时候,鉴权啥的都已经完成了,不需要关心了
    LeeReamond
        20
    LeeReamond  
       2021 年 11 月 24 日
    @banlifeather4 很正常的需求,不知道你想问什么,比如手机作为唯一身份认证终端的时代 ,丢手机当然不是 0 概率事件,其他认证方式同理,你这问题属于想的太多做得太少,做了就遇到这种需求了。
    sujin190
        21
    sujin190  
       2021 年 11 月 24 日
    @banlifeather4 #18 你这个并没有解决问题吧,且不说最简单的设备不在线就走不通,毕竟不是大厂设备在线率不能比,再者用户改密码大多可能有异常登录之类的,既然异常登录了,那说不定 WS 就没用了呢,所以你这个方案是无所谓的正常改密码能正常踢下线,必须要改密码的异常情况恰恰可能反而踢不下线了,反着来么
    mosakashaka
        22
    mosakashaka  
       2021 年 11 月 24 日   1
    jwt 踢用户做点改造不就得了,加个自定义属性。
    spring security 没明白为什么不用,而要自己造轮子。。
    securityCoding
        23
    securityCoding  
       2021 年 11 月 24 日
    登录态拦截在网关做,业务中从上下文获取属性即可根本不要关注登录态.省时省力省心
    timethinker
        24
    timethinker  
       2021 年 11 月 24 日   7
    登录其实就是认证,认证与授权是两个相对独立的过程。

    认证解决的问题:你是谁?一般只是简单的通过标识(用户名)和凭证(密码)来确定身份。确定身份以后,认证系统一般会发放一个 Token (令牌)或者直接绑定身份信息并关联当前的 sessionid (会话,通过 cookie 传递)。

    授权解决的问题:在已认证的情况下,也就是我知道你是谁的情况下,你能做什么?

    关于密码:不要使用明文,后端也不要接收明文(固然有 TLS ),前端可以使用 BCrypt 慢哈希生成密码摘要,不要在后端使用慢哈希。后端生成(注册)/获取(登录)动态盐值,与前端发过来的摘要结合再次哈希一遍得到最终的摘要信息。

    关于 JWT:JWT 只是作为令牌的一种承载形式,它不可伪造,不可篡改,表达了签发此令牌的真实意图,但是不要将敏感信息放进去。好处固然有,例如完全可以在不跟签发者通讯的情况下对其进行验证(签名以及有效期),但是涉及到撤销的情况下,就必须记录每一个令牌的状态( jti 是每一个令牌的 ID ),可以建立令牌黑名单机制,虽然丧失了完全的无状态好处,但是验证这个比较轻量级。

    我想说的就是可以根据场景结合混合使用不同的技术,关于安全这一块,不要自己去发明东西,大胆的使用经过时间检验的通用方法,具体如何实现只是细节问题(比如框架,亦或是自己手写),但是在流程上,概念上一定要有清晰的认知。
    slowgen
        25
    slowgen  
       2021 年 11 月 24 日 via Android
    如果项目前后端分离得很彻底,可以把原来存在 cookie 的 session id 丢到 local storage ,请求的时候取出来追加到 header 上,可以从根本上杜绝 csrf 攻击,还能让扫描器或者等保服务提供商的初级安全人员一脸懵逼
    Casbin
        26
    Casbin  
    PRO
       2021 年 11 月 24 日
    可以试试 Casdoor: https://v2ex.com/t/803669 ,支持与 Spring-Boot 项目集成: https://github.com/casdoor/casdoor-spring-boot-example
    ihwbunny
        27
    ihwbunny  
       2021 年 11 月 24 日
    为啥没人提多设备验证
    danieladu
        28
    danieladu  
       2021 年 11 月 24 日
    yangzzzzzz
        29
    yangzzzzzz  
       2021 年 11 月 24 日
    简单点 jwt 单 token ,复杂点双 token 。
    MonikaCeng
        30
    MonikaCeng  
       2021 年 11 月 24 日 via Android
    我之前做短信登录,安全策略是,同 ip 发短信超过 5 条该 ip 需要验证码。当日短信发送总量超过 1000 条,当日所有人需要验证码
    getoffworkontime
        31
    getoffworkontime  
       2021 年 11 月 24 日
    直接用阿里云的 API 网关
    leeg810312
        32
    leeg810312  
       2021 年 11 月 24 日 via Android
    jwt 那么多好处为什么不用? jwt 跨域方便,横向扩展方便,代码什么都不用改,cookie 和 session 可以吗? jwt 没有提供吊销,但也容易补这个特性。生成时缓存一份,校验前去缓存查一下,吊销时把缓存里的删了就好了。jwt 的好处也用了,缺点也弥补了。
    joApioVVx4M4X6Rf
        33
    joApioVVx4M4X6Rf  
       2021 年 11 月 25 日
    @yangzzzzzz 求教双 token 是啥啊?是 access_token 和 refresh_token 吗
    ArmstrongLiu
        34
    ArmstrongLiu  
       2021 年 11 月 25 日
    @qwe520liao #24 关于“关于密码” 这块有两个疑问:

    1. Bcrypt 哈希算法每次生成的哈希值都是不同的(即使是相同的密码),这样后端是如何校验密码的正确性的呢?

    2. 前后端交互时不使用明文的原因是什么?如果出现别人通过抓包或者请求拦截获取到密码或者密码摘要,这二者造成的后果是不是都是一样的?因为不管是用密码或者是密码摘要模拟请求,后端的密码验证都是可以通过的。
    timethinker
        35
    timethinker  
       2021 年 11 月 25 日
    @ArmstrongLiu
    1 、前端 Bcrypt 是可能的,我们需要的就是把“慢”这个过程放到客户端内,代码细节可以看一下我刚创建的这个测试,需要一个固定的盐值: https://jsfiddle.net/4zdw1jab/

    2 、不使用明文不仅仅只是说为了传输上的考虑,明文就是“烫手山芋”,只要生成摘要的过程是安全可靠的,其实我们根本就不需要明文。其他的顾虑包括但不限于意外的日志输出或者其他的安全漏洞,所以彻底的做法就是后端根本就不接收明文。当然这一条只是作为一个建议,如果手动模拟注册请求给后端接口发送的就是明文,那么当然也可以模拟登录用之前的明文,关于这种“非法”注册的用户,当然也就排除在正常的产品流程之外了。
    ZeroDu
        36
    ZeroDu  
       2021 年 11 月 25 日
    自己写个拦截器 + uuid +redis 无烦恼。
    yangzzzzzz
        37
    yangzzzzzz  
       2021 年 11 月 25 日
    @v2exblog 是的
    ArmstrongLiu
        38
    ArmstrongLiu  
       2021 年 11 月 26 日
    @qwe520liao 如果前端使用固定盐值,那应该没有问题。我之前使用 python ( passlib.hash )进行测试时一直没有使用盐值,所以它每次都自动生成 salt ,就导致每次的 hash 值不同。
    letitbesqzr
        39
    letitbesqzr  
       2021 年 11 月 29 日
    sa-token 好用
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2665 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 89ms UTC 10:19 PVG 18:19 LAX 03:19 JFK 06:19
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86