美文网首页JWTweb后端移动
JWT在身份认证方面的应用

JWT在身份认证方面的应用

作者: 贾老师和他的朋友们 | 来源:发表于2017-03-22 18:30 被阅读6879次

    JWT,Json web token。因为在项目中准备应用,总结下,理清思路,希望对团队有帮助。除简介外,都融合了我个人的理解,不希望对别人产生误导。网络让自媒体很容易,一定加以分析,全盘照收是很危险的;即使是读书,也要分析,尽信书不如无书。

    简介

    参考《jwt简介》,我认为很基础,原文翻译,比较客观,就不重复了。

    JWT应用场景?

    简介中提到两个场景,我认为主要第一种--身份认证。为什么采用这种方式呢?我总结了下

    1、json格式简单,相比xml,我更喜欢json;Self-contained,一般都翻译成自包含,意思是jwt中已经有了你需要的全部信息,拿出来用就行。

    2、同session相比,性能更好一些,省去了处理分布session的问题;对于大行其道的restful来讲,支持得很好;浏览器+app+pc,这种多终端开发,是很好的选择。

    如果可以,新系统不再使用session保存用户信息。对于我们自己的platina开发平台,可以平滑过渡到jwet,让开发人员感觉不到。

    JWT有什么好处?

    1、支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输.

    2、无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.

    4、更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可.

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

    6、更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。

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

    8、性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析要费时得多.

    9、不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理.

    10、基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft).

    流程

    1、用户认证。认证方式可能很多,自己认证或者sso。

    2、认证后,服务器构造JWT。

    3、把JWT返回客户端,客户端存储。

    4、客户端访问服务器,带上JWT。

    5、服务器端判断JWT是否正确并且没有超时,正常,向下流转;否则,转到授权。

    服务器端

    服务器端主要有2件事,我结合java说明下,j wt.io上介绍了几个java类库,根据个人喜好选择。之前使用一个sso,用Nimbus,也支持jwt,但是他却依赖net.minidev.json.JSONObject,就放弃了;后来采用jjwt,依赖jackson。

    1、生成jwt

    1.1、生成jwt的时机,认证之后,返回认证结果之前。

    1.2、Payload(很多翻译是直译,对于理解没有任何帮助)中如何设计属性,这个对于可读性比较重要。

    根据JWT的标准,这些claims可以分为以下三种类型:

    a. Reserved claims(保留),它的含义就像是编程语言的保留字一样,属于JWT标准里面规定的一些claim。JWT标准里面定好的claim有:

    iss(Issuser):代表这个JWT的签发主体;

    sub(Subject):代表这个JWT的主体,即它的所有人;

    aud(Audience):代表这个JWT的接收对象;

    exp(Expiration time):是一个时间戳,代表这个JWT的过期时间;

    nbf(Not Before):是一个时间戳,代表这个JWT生效的开始时间,意味着在这个时间之前验证JWT是会失败的;

    iat(Issued at):是一个时间戳,代表这个JWT的签发时间;

    jti(JWT ID):是JWT的唯一标识。

    b. Public claims,略(不重要)

    c. Private claims,这个指的就是自定义的claim。比如前面那个结构举例中的admin和name都属于自定的claim。这些claim跟JWT标准规定的claim区别在于:JWT规定的claim,JWT的接收方在拿到JWT之后,都知道怎么对这些标准的claim进行验证;而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行。

    1.3、生成jwt的代码

    SecretKeySpec key = getKey();//getKey自己处理

    Map claims = new HashMap();

    claims.put("uid", userInfo.getAccountId()+"");

    claims.put("user_name", userInfo.getUserName());

    claims.put("nick_name",userInfo.getUserAttribute(PlatinaUser.NICK_NAME));

    JwtBuilder builder = Jwts.builder()

    .setClaims(claims)----一定先于下面的set方法,否则覆盖。

    .setIssuer("bmtech.com")

    .setSubject(userInfo.getUserNum())

    .setNotBefore(now)

    .signWith(signatureAlgorithm, key);

    return builder.compact();

    2、处理jwt

    Jwtjwt = Jwts.parser().setSigningKey(getKey()).parse(token);

    Claims claims =  jwt.getBody();

    客户端

    jwt存储方式自己灵活掌握。

    web:cookie/localStorage/sessionStorage/;

    app:内存

    安全

    JWT是否安全?

    既然jwt被很多大型公司采用,安全性一定是有保证的。

    要保证私钥的安全性,来保障签名的安全。

    有人提到jwt暴露签名算法(alg),而且会有None(无签名),所以建议隐去alg。一般的协议制定都会考虑扩展性和普适性。但是我们在应用中可以采用我们默认的算法,而不是根据alg去处理。

    常见安全问题及处理?

    1、XSS(Cross Site Script)

    把token存储在cookie中,同时设置httpOnly。

    2、CSRF(cross-site request forgery)

    2.1、判断reffer。系统改动最小,通过filter就可以完成。

    2.2、在参数中传token。

    2.3、通过header传递token。(推荐)

    相关文章

      网友评论

      • 86608183709c:请问如果使用这种方案 “2.3、通过header传递token。(推荐)”

        在前后端分离的方案中,前端如何保存token?
      • 彼得堡的遗书:如果被攻击者直接拿到用户客户端的token伪造请求呢?
        贾老师和他的朋友们:@彼得堡的遗书 拿到的过程就是攻击的过程,所以应该如何预防攻击
      • a991b6f98cfa:喜阅楼主佳文,这文章叼!JWT条例清晰,看后就恍然大悟,感激不敬!Nice ,Mark!!!
      • 41a3cfda8e4d:不懂,但赞一个

      本文标题:JWT在身份认证方面的应用

      本文链接:https://www.haomeiwen.com/subject/rpdunttx.html