zoukankan      html  css  js  c++  java
  • 几种常见登录验证的方式总结

    1. Cookie-Session 认证

    早期互联网以 web 为主,客户端是浏览器,所以 Cookie-Session 方式最那时候最常用的方式,直到现在,一些 web 网站依然用这种方式做认证。
    认证过程大致如下:

    1. 用户输入用户名、密码或者用短信验证码方式登录系统;
    2. 服务端验证后,返回一个 SessionId [SessionId与用户信息进行关联,通过SessionId可以得到用户信息],客户端将 SessionID 存到 cookie,下次访问的时候带着SessionID;
    3. 当客户端再发起请求,自动带上 cookie 信息,服务端通过 cookie 获取 Session 信息进行校验,判断对应用户是否存在;

    弊端

    • 只能在 web 场景下使用,如果是 APP 中,不能使用 cookie 的情况下就不能用了;
    • 即使能在 web 场景下使用,也要考虑跨域问题,因为 cookie 不能跨域;
    • cookie 存在 CSRF(跨站请求伪造[前后端分离的项目])的风险;
    • 如果是分布式服务做了集群,第一次登录请求访问的是A服务,第二请求来到了B服务,B服务就没有第一次请求访问登录得到的Session Id. 此时还需要考虑 Session 同步问题;



    2. 基于 Cookie-Session 的改造认证

    由于传统的 Cookie-Session 认证存在诸多问题,可以把上面的方案改造一下。改动的地方如下:

    1. 不用 cookie 做客户端存储,改用其他方式,web 场景下让前端使用 local storage(局部存储器。它是html5新增的一个本地存储API),APP 中使用客户端数据库,这样就实现了跨域,并且避免了 CSRF ;
    2. 服务端也不存 Session 了,把 Session 信息拿出来存到 Redis 等内存数据库中,这样即提高了速度,又避免了 Session 同步问题;

    经过改造之后变成了如下的认证过程:

    1. 用户输入用户名、密码或者用短信验证码方式登录系统;
    2. 服务端经过验证,将认证信息构造好的数据结构存储到 Redis 中,并将 key 值返回给客户端;
    3. 客户端拿到返回的 key,存储到 local storage 或本地数据库;
    4. 下次客户端再次请求,把 key 值附加到 header 或者 请求体中;
    5. 服务端根据获取的 key,到 Redis 中获取查询相关value得到认证信息;

    弊端:

    1. 可能存在单点故障的问题,redis宕机后,全部用户都得重新登录。
    2. redis可以做集群解决单点故障问题。但回过头来一想, 就为了这小小的session我还得为他付出这么多精力,得不偿失。
    3. 也会占用redis的内存,用户多的话,要占很多redis内存。



    3. Token认证

    例子:https://blog.csdn.net/qq_20786911/article/details/104687728?utm_source=app&app_version=4.10.0
    认证过程大致如下:

    1. 用户在登录表单中输入用户名和密码,然后点击登录。
    2. 请求通过在请求头中携带token发送登录请求之后,通过在后端查询数据库验证用户的合法性。【通常会让用户表与token有关联关系,一般还会对token加密,而且还会设置过期时间。所以一般采用redis来存储,key存token,值存用户相关信息】
    3. 在每次发送访问请求时提供token信息(一般是服务器采用filter过滤器或拦截器来判断),然后根据这个token得到相关用户信息(如:用户id)去数据库查得到用户信息进行验证账号密码等,通过则让用户访问服务端接口,不通过则拒绝访问。

    弊端:

    1. 这一切其实和session id没有本质区别。
    2. 需要用token去数据库查询是否有相应用户。
    3. 也会占用redis的内存,用户多的话,要占很多redis内存。



    4. 基于Token的JWT认证

    JWT:Json web token 是为了在网络应用环境间传递声明而执行的一种基于JSON传输格式的开放标准,可实现无状态、分布式的Web应用授权。
    先说缺点:
    使用JWT时,有个十分头疼的问题。用户主动注销,服务器不能让token主动失效。就是说token没有过期前,你想让它提前停止使用,不好意思没得办法。
    解决思路有几种,不过都不是很完美。要么你就不解决JWT退出登录的问题,你在设置对token设置过期的时候,不要设置太久,设置1天,1天过后就失效。

    认证过程大致如下:

    1. 用户登陆服务器,服务端验证用户账号密码,使用secret生成JWT令牌【一般还会设置过期时间,在生成token的时候指定】,然后将令牌返回给客户端。
    2. 客户端访问服务端的时候,在请求头中带上这个令牌,服务端使用secret去验证令牌是否合法,合法则让用户访问服务器接口,不合法则拒绝。
    3. 服务器并不保存token,就不用像上述方式,拿到token还得去redis数据库验证,根据token得到对应值(一般时用户的id,拿到用户id后,去数据库查用户信息,得到账号密码进行校验)。(注意理解这里,因为生成的JWT令牌(是按照某种规则生成的,==它可以包含用户信息,比如我们把用户id或带有权限标识的用户JSON数据[做权限校验]存到JWT令牌,他第二次带着JWT令牌登录时,解析JWT令牌得到他的用户id,此时拿着用户id去查询那个用户信息,得到账号密码进行校验=。))。

    JWT令牌结构:

        Header(头部)        是token的一部分,用来存放token的类型和编码方式,通常是使用base-64编码
        Payload(负载)       包含了信息,你可以存放任一种信息,比如用户信息,产品信息等,它们都是使用base-64编码方式【编码方式取决于你在Header中设置的编码方式】进行存储
        Signature(签名)     包括了header,payload和密钥的混合体,密钥必须安全地保存储在服务端
    
        发送给服务器的令牌样子是AAAA(头部).BBBB(负载).CCCC(签名)的形式。
    

    Header:
    通常由两部分组成,令牌的类型与所使用的签名算法。它会被Base64编码编成JWT结构的第一部分。【Base64编码:不是一种加密,就是一种编码,它能被解码】

    {
      "alg":"HS256",  // 签名算法  默认 HS256
      "typ":"JWT"  // 令牌的类型  默认 JWT
    }
    

    Payload:
    用于包含声明信息,一般用来声明用户数据。它会被Base64编码编成JWT结构的第二部分。【Base64编码:不是一种加密,就是一种编码,它能被解码】
    因为能被解密,所以这里面不要放特别敏感的用户信息。

    {
      "name":"zhangsan",
      "age":23,
      "email":"971410648@qq.com"
    }
    

    Signature:
    他是基于Header,Payload被Base64编码后加上我们提供的一个私钥,这个私钥只有服务端知道,然后就会将3者使用Header里面指定的签名算法进行签名生成JWT。
    作用:保证JWT没有被篡改。

    token = `${base64UrlEncode(header)}.${base64UrlEncode(payload)}`.signature)
    





    5. SSO单点登录

    单点登录:指在公司内部搭建一个公共的认证中心,公司下的所有产品的登录都可以在认证中心里完成,一个产品在认证中心登录后,再去访问另一个产品时,可以不用再登录,即可获取登录状态。



    6. OAuth第三方登录



    7. 总结

    • Cookie + Session 历史悠久,适合于简单的后端架构,需开发人员自己处理好安全问题。
    • 基于Token的JWT 方案对后端压力小,适合大型分布式的后端架构,但已分发出去的 token ,如果想收回权限,就不是很方便了。
    • SSO 单点登录,适用于中大型企业,想要统一内部所有产品的登录方式。
    • OAuth 第三方登录,简单易用,对用户和开发者都友好,但第三方平台很多,需要选择合适自己的第三方登录平台


    8. JWT登录案例:

    基于自定义注解+拦截器实现(没有指定过期时间):https://blog.csdn.net/qq_37992974/article/details/90236581?utm_source=app&app_version=4.10.0
    基于自定义注解+拦截器实现(指定过期时间):https://blog.csdn.net/lzm19930310/article/details/109626578?utm_source=app&app_version=4.10.0
    设置过期时间:https://blog.csdn.net/qq_33229669/article/details/87204400?utm_source=app&app_version=4.10.0

    如何让token失效:https://blog.csdn.net/weixin_39777213/article/details/113410928?utm_source=app&app_version=4.10.0

  • 相关阅读:
    《敏捷软件需求》阅读笔记三
    《敏捷软件需求》阅读笔记二
    《敏捷软件需求》阅读笔记一
    《需求工程-软件建模与分析》阅读笔记三
    《需求工程-软件建模与分析》阅读笔记二
    《需求工程-软件建模与分析》阅读笔记一
    C#.NET程序设计实验三实验报告
    C#.NET程序设计实验二实验报告
    C#.NET程序设计实验一实验报告
    oracle——存储数据时的编码问题
  • 原文地址:https://www.cnblogs.com/itlihao/p/14846026.html
Copyright © 2011-2022 走看看