zoukankan      html  css  js  c++  java
  • 使用Json Web Token设计Passport系统

    一、Token Auth机制

    基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中。

    相比原始的Cookie+Session方式,更适合分布式系统的用户认证,绕开了传统的分布式Session一致性等问题。

    基于Token的身份验证的主流程如下:

    用户通过用户名和密码发送请求;
    程序验证;
    程序返回一个签名的token 给客户端;
    客户端储存token,并且每次用于每次发送请求。

    二、相比Cookie认证的优势

    支持跨域跨站点访问:

    Cookie是不允许垮域访问的,可以通过设置顶级域名的方式实现部分跨域,但是跨站点的访问仍然不支持,
    如果使用Token机制,就可以通过HTTP头传输用户认证信息,从而更好的实现跨域跨站点。

    无状态:

    Token机制在服务端不需要存储session信息,Token自身包含了登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息;

    去耦:不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可;

    更适用于移动应用:

    当客户端是原生应用时,Cookie是不被支持的,虽然目前Webview的方式可以解决Cookie问题,

    但是显然采用Token认证机制会简单得多;

    安全性更强:

    因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范;

    标准化易扩展:

    可以采用标准化的 JSON Web Token (JWT),对以后系统接入Node等纯前端开发更便捷;

    相比Session一致性提高性能:

    相比服务端保存Session一致性信息,并查询用户登录状态,一般来说Token的验证过程(包含加密和解密),性能开销会更小。

    三、JSON Web Token标准的设计

    JWT 标准的 Token 有三个部分:

    header.payload.signature

    三个部分中间用点分隔开,并且都使用 Base64 编码,所以生成的 Token 类似这样:

    ewogICJ0eXAiOiAiSldUIiwKICAiYWxnIjogIkhTMjU2Igp9.ewogImlzcyI6ICJjaGJsb2dzLmNvbSIsCiAiZXhwIjogIjE0NzA3MzAxODIiLAogInVpZCI6ICIxMjM0NWFiY2RlIiwKfQ.9q2eq8sa374ao2uq9607r6qu6

    (1)Header报头

    header 部分主要包括两部分,一个是 Token 的类型,另一个是使用的算法,
    比如下面类型就是 JWT,使用的算法是 HS256。

    {
    "typ": "JWT",
    "alg": "HS256"
    }

    Header内容要用 Base64 的形式编码,所以就变成这样:
    ewogICJ0eXAiOiAiSldUIiwKICAiYWxnIjogIkhTMjU2Igp9

    (2)Payload载荷部分

    Payload 里面是 Token 的具体内容,这部分内容可以自定义,JWT有标准字段,也可以添加其它需要的内容。
    标准字段:
    iss:Issuer,发行者
    sub:Subject,主题
    aud:Audience,观众
    exp:Expiration time,过期时间
    nbf:Not before
    iat:Issued at,发行时间
    jti:JWT ID

    这是一个典型的payload信息,包含了发行者(网站)、过期时间和用户id:
    {
    "iss": "chblogs.com",
    "exp": "1470730182",
    "uid": "12345abcde",
    }

    这部分内容同样要用Base64 编码,生成编码类似如下格式:

    ewogImlzcyI6ICJjaGJsb2dzLmNvbSIsCiAiZXhwIjogIjE0NzA3MzAxODIiLAogInVpZCI6ICIxMjM0NWFiY2RlIiwKfQ==

    (3)Signature签名部分

    签名部分主要和token的安全性有关,Signature的生成依赖前面两部分。
    首先将Base64编码后的Header和Payload用.连接在一起,

    ewogICJ0eXAiOiAiSldUIiwKICAiYWxnIjogIkhTMjU2Igp9.ewogImlzcyI6ICJjaGJsb2dzLmNvbSIsCiAiZXhwIjogIjE0NzA3MzAxODIiLAogInVpZCI6ICIxMjM0NWFiY2RlIiwKfQ


    对这个字符串使用HmacSHA256算法进行加密,这个密钥secret存储在服务端,前端不可见,

    String str="ewogICJ0eXAiOiAiSldUIiwKICAiYWxnIjogIkhTMjU2Igp9."
    				+ "ewogImlzcyI6ICJjaGJsb2dzLmNvbSIsCiAiZXhwIjogIjE0NzA3MzAxODIiLAogInVpZCI6ICIxMjM0NWFiY2RlIiwKfQ";
        	byte[] inputData = str.getBytes();  
    		String key = Coder.initMacKey();  
    		BigInteger sha = new BigInteger(Coder.encryptHMAC(inputData, key));  
    		System.out.println("HS256加密后——"+sha.toString(32));
    

      


    下面使用密钥 THISSHA 进行加密:
    9q2eq8sa374ao2uq9607r6qu6

    然后将Signature和前面两部分拼接起来,得到最后的token:

    ewogICJ0eXAiOiAiSldUIiwKICAiYWxnIjogIkhTMjU2Igp9.ewogImlzcyI6ICJjaGJsb2dzLmNvbSIsCiAiZXhwIjogIjE0NzA3MzAxODIiLAogInVpZCI6ICIxMjM0NWFiY2RlIiwKfQ.9q2eq8sa374ao2uq9607r6qu6

    四、JWT认证的实现

    常规的token保存在sessionStorage或者localStorage中,每次请求时将token加在http请求的Header中,

    下面是典型的token认证方式:

    1.客户端登录时通过账号和密码到服务端进行认证,认证通过后,服务端通过持有的密钥生成Token,Token中一般包含失效时长和用户唯一标识,如用户ID,服务端返回Token给客户端;
    2.客户端保存服务端返回的Token;
    3.客户端进行业务请求时在Head的Authorization字段里面放置Token,如: 
    Authorization: Bearer Token 
    4.服务端对请求的Token进行校验,如果Token不是存放在Cookie中,需要解决用户主动注销,但设置的过期时间并未过期问题。

    用户注销时可以把还在失效内的Token储存在Redis等缓存中,验证时查找Token是否存在,如果Token在Redis中存在,则说明用户已注销;如果Token不存在,则校验通过。 
    5.服务端可以通过从Token取得的用户唯一标识进行相关权限的校验,并把此用户标识赋予到请求参数中,业务可通过此用户标识进行业务处理; 

    还有一种方式是把token保存在Cookie中,这时就不需要在服务端保存token的值,用户注销时直接清除Cookie就可以,

    这种方式不需要在服务端储存token的值,认证过程如下:


    五、JWT标准的安全性

    (1)如何访问CSRF攻击

    CSRF (Cross Site Request Forgery),指在一个浏览器中打开了两个标签页,其中一个页面通过窃取另一个页面的 cookie 来发送伪造的请求,因为 cookie 是随着请求自动发送到服务端的。

    (2)如何保证token的安全性

    客户端不需要持有密钥,由服务端通过密钥生成Token;

    在JWT中,不应该在Payload里面加入任何敏感的数据,如用户密码等信息,因为payload并没有做加密,只是一个Base64的编码,
    攻击者拿到token以后就可以得到用户敏感信息;

    参考资料:

    基于 Token 的身份验证

    JSON Web Token - 在Web应用间安全地传递信息

  • 相关阅读:
    NYOJ-301递推求值
    二叉树
    从c到c++
    NYOJ-93汉诺塔(三)
    历届试题 最大子阵
    最大子序列和最大子矩阵
    【贪心】电视节目安排
    【贪心】线段覆盖
    【贪心】取数游戏
    【贪心】智力大冲浪
  • 原文地址:https://www.cnblogs.com/binyue/p/4812798.html
Copyright © 2011-2022 走看看