zoukankan      html  css  js  c++  java
  • 普通的用户认证,登录

    基于 session 和基于 token(jwt [json web token]) 的用户认证方式

      要实现用户的登录,在我们这里的前后端分离的开发中和之前基于模板的browser开发是有一定区别的,区别主要在于服务端存放数据与否。

      多数网站用户认证都是基于 session 的,即在服务端存放用户相关的 session 数据,而发给客户端 sesssion_id (其实也是token的一种)存放到 cookie 中,这样用客户端请求时带上 session_id 就可以验证服务器端是否存在 session 数据,以此完成用户认证。

    这种认证方式,优点是可以更好的在服务端对会话进行控制,安全性比较高(session_id 随机)。但是服务端需要存储 session 数据(如内存或数据库).缺点是   ①增加维护成本和减弱可扩展性(多台服务器),②存在基于cookie的 CSRF攻击,③原生 app 等前端没有浏览器 的cookie 功能,使用这种服务接口会相对麻烦。

       基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。用户验证后,服务端生成一个 token(hash 或 encrypt)发给客户端,客户端可以放到 cookie 或 localStorage 中,每次请求时在 Header 中带上 token ,服务端收到 token 通过验证后即可确认用户身份。这种方式相对 于cookie 的认证方式就简单一些,服务端不用存储认证数据.

    相应地具有以下优点:①易维护、扩展性强② token 储存在 localStorage 中可避免 CSRF ③ web 和 app 应用这用接口都比较简单。不过这种方式在加密或解密的时候会有一些性能开销(好像也不是很大),有些对称加密存在安全隐患(aes cbc 字节翻转攻击)。

    一、基于session

    1. 登录
        * 用户输入账号密码,从客户端传到服务端
        * 服务端效验账号密码是否匹配
        * 匹配时,将用户信息存放到session中。session.setAttribute(user);
    
    当执行其他接口请求时,在服务端判断是否已登录,即查看session中是否存在用户数据。session.getAttribute(user)
    
    2. 忘记密码,回答问题答案,注册用户时,设置的,此时就是回答问题,找回密码
        * 输入用户名,检验是否存在该用户。
        * 找到问题,输入问题答案
        * 回答正确,随机生成一个token,存入缓存中,并传给客户端。
        * 客户端修改密码后,将新密码和token传到服务端。
    
    token的作用:如果答案正确,那么就针对这个用户,把一个token存入缓存中。当该用户想改密码时,将传入的token跟缓存中的token进行比较,如果一致,则认为是该用户在操作。token要过期时间的原因是,这次修改需要保证在一段时间内有效,过期就无效了。
    这在互联网上修改密码是一个很常用的做法,例如,忘记密码修改邮件里面给的链接,都会有一个提示,告诉你,这个修改密码的链接在10个小时之内有效,过期请重新获取该链接~

    基于session认证所显露的问题

    Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

    扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

    CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

    二、基于token(jwt)鉴权机制

    基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。
    
    流程上是这样的:
    
        *用户使用用户名密码来请求服务器
       * 服务器进行验证用户的信息
       * 服务器通过验证发送给用户一个token
       * 客户端存储token,并在每次请求时附送上这个token值
       * 服务端验证token值,并返回数据
       * 这个token必须要在每次请求时传递给服务端,它应该保存在请求头里,
       * 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了 Access-Control-Allow-Origin:*。*
    
    token的优点
      支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输。
      无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息。
      更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可。
      去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可。
      更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
      CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
      性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析要费时得多。
      不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理。
      基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)。
          因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
          因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
          便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。 它不需要在服务端保存会话信息, 所以它易于应用的扩展。
  • 相关阅读:
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    206. Reverse Linked List
    205. Isomorphic Strings
    204. Count Primes
    203. Remove Linked List Elements
    201. Bitwise AND of Numbers Range
    199. Binary Tree Right Side View
    ArcGIS API for JavaScript 4.2学习笔记[8] 2D与3D视图同步
  • 原文地址:https://www.cnblogs.com/FondWang/p/11670375.html
Copyright © 2011-2022 走看看