• JWT简单介绍


    目录

    JWT

    概述

    token认证和session认证的区别

    传统的session认证

    基于session认证所显露的问题

    基于token的鉴权机制

    JWT 的主要应用场景

    优点

    JWT搭建(基于java)

    创建生成token的方法

    验证token是否有效

    获得 token 中 playload 部分数据


    概述

    Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT 可以使用 HMAC 算法或者是 RSA 的公私秘钥对进行签名。

    token认证和session认证的区别

    传统的session认证

    我们知道,http 协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据 http 协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为 cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于 session 认证。

    但是这种基于 session 的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来.

    基于session认证所显露的问题

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

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

    CSRF(跨站请求伪造):因为基于cookie来进行用户识别的,cookie如果被截获,那么用户就很容易的收到跨站请求的伪造攻击

    基于token的鉴权机制

    它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token 认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

    流程:

    1. 用户使用账号和密码发出 post 请求;

    2. 服务器使用私钥创建一个 jwt;

    3. 服务器返回这个 jwt 给浏览器;

    4. 浏览器将该 jwt 串在请求头中像服务器发送请求;

    5. 服务器验证该 jwt;

    6. 返回响应的资源给浏览器

    JWT 的主要应用场景

    身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录中比较广泛的使用了该技术。信息交换在通信的双方之间使用JWT 对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。

    优点

    1.简洁(Compact): 可以通过 URL,POST 参数或者在 HTTP header 发送,因为数据量小,传输速度也很快

    2.自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库

    3.因为 Token 是以 JSON 加密的形式保存在客户端的,所以JWT 是跨语言的,原则上任何 web 形式都支持。

    4.不需要在服务端保存会话信息,特别适用于分布式微服务。

    5.由于私钥加密的缘故,也自然而然会更加的安全

    JWT搭建(基于java)

    1. <dependency>
    2. <groupId>com.auth0</groupId>
    3. <artifactId>java-jwt</artifactId>
    4. <version>3.8.2</version>
    5. </dependency>

    创建生成token的方法

    1. /**
    2. * jwt 生成 token
    3. * @param id
    4. * @param account * @return
    5. */
    6. public static String token (Integer id, String account){
    7. String token = "";
    8. try {
    9. //过期时间 为 1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
    10. Date expireDate = new Date(new Date().getTime() + 10*1000);
    11. //秘钥及加密算法
    12. Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
    13. //设置头部信息
    14. Map header = new HashMap<>();
    15. header.put("typ","JWT");
    16. header.put("alg","HS256");
    17. //携带 id,账号信息,生成签名
    18. token = JWT.create()
    19. .withHeader(header)
    20. .withClaim("id",id)
    21. .withClaim("account",account)
    22. .withExpiresAt(expireDate)
    23. .sign(algorithm);
    24. }catch (Exception e){
    25. e.printStackTrace(); return null;
    26. }return token;
    27. }

    验证token是否有效

    1. public static boolean verify(String token){
    2. try {
    3. //验签
    4. Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
    5. JWTVerifier verifier = JWT.require(algorithm).build();
    6. DecodedJWT jwt = verifier.verify(token); return true;
    7. } catch (Exception e) {//当传过来的 token 如果有问题,抛出异常
    8. return false;
    9. }
    10. }

    获得 token 中 playload 部分数据

    1. /**
    2. * 获得 token 中 playload 部分数据,按需使用
    3. * @param token
    4. * @return
    5. */
    6. public static DecodedJWT getTokenInfo(String token){
    7. return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);
    8. }

    用户登录成功后将用户 id 和账号存储到 token 中返回给客户端,之后客户端每次请求将 token 发送到服务器端验证, 在服务器中进行验证.

  • 相关阅读:
    zabbix-proxy分布式监控
    GitHub下载太慢的解决方案
    LeetCode 阿姆斯特朗数
    好消息:用 vue3+layui 共同铸造我们新的项目
    基于STM32+华为云IOT设计的智能冰箱(华为云IOT)
    从大龄程序员现状聊聊出路
    【前段基础入门之】=>玩转【CSS】开篇章!
    深度学习DAY3:FFNNLM前馈神经网络语言模型
    【Python Web】Flask框架(五)Bootstrap登录和后台管理案例
    JavaScript 设计模式之代理模式
  • 原文地址:https://blog.csdn.net/weixin_51971817/article/details/127886992