剖析JWT,及其使用案例

这篇具有很好参考价值的文章主要介绍了剖析JWT,及其使用案例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是JWT
  • JWT 是一个开放标准,它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名

  • 简单来说: 就是通过一定规范来生成token,然后可以通过解密算法逆向解密token,这样就可以获取用户信息

  • 优点

    • 生产的token可以包含基本信息,比如id、用户昵称、头像等信息,避免再次查库
    • 存储在客户端,不占用服务端的内存资源
  • 缺点

    • token是经过base64编码,所以可以解码,因此token加密前的对象不应该包含敏感信息,如用户权限,密码等
    • 如果没有服务端存储,则不能做登录失效处理,除非服务端改秘钥
JWT格式组成 头部、负载、签名
  • header+payload+signature
    • 头部:主要是描述签名算法
    • 负载:主要描述是加密对象的信息,如用户的id等,也可以加些规范里面的东西,如iss签发者,exp 过期时间,sub 面向的用户
    • 签名:主要是把前面两部分进行加密,防止别人拿到token进行base解密后篡改token
关于jwt客户端存储
  • 可以存储在cookie,localstorage和sessionStorage里面
代码实现
  • 依赖引入

    <!-- JWT相关 -->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.7.0</version>
    </dependency>
    
  • JWTUtil类,封装了生产token方法和校验token方法

    @Slf4j
    public class JWTUtil {
        /**
         * 主题
         */
        private static final String SUBJECT = "xtw";
        /**
         * 加密秘钥
         */
        private static final String SECRET = "xtw.com";
        /**
         * 令牌前缀
         */
        private static final String TOKEN_PREFIX = "xtwcloud-link";
        /**
         * 过期时间 7天
         */
        private static final long EXPIRED = 1000*60*60*24*7;
    
        /**
         * 生成token
         * @param loginUser
         * @return
         */
        public static String geneJsonWebToken(LoginUser loginUser){
            if(loginUser == null){
                throw new NullPointerException("对象为空");
            }
    
            String token = Jwts.builder().setSubject(SUBJECT)
                    // 配置payload
                    .claim("head_img",loginUser.getHeadImg())
                    .claim("account_no",loginUser.getAccountNo())
                    .claim("username",loginUser.getUserName())
                    .claim("mail",loginUser.getMail())
                    .claim("phone",loginUser.getPhone())
                    .claim("auth",loginUser.getAuth())
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(CommonUtil.getCurrentTimestamp()+EXPIRED))
                    .signWith(SignatureAlgorithm.HS256,SECRET).compact();
            token = TOKEN_PREFIX + token;
            return token;
        }
    
        /**
         * 校验token
         * @param token
         * @return
         */
        public static Claims checkJWT(String token){
            try {
                final Claims claims = Jwts.parser().setSigningKey(SECRET)
                        .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                        .getBody();
    
                return claims;
            }catch (Exception e){
    
                log.info("jwt 校验失败");
                return null;
            }
    
        }
    }
    
    
  • 案例

    • 用户初次登录或者token过期,登录成功返回JWT令牌

      public JsonData login(AccountLoginRequest loginRequest) {
          // 校验用户账号和密码,等...  TODO 
          
          // 对象变迁 loginRequest -> DO -> DTO(loginUser)
          // loginRequest:前端输入
          // DO:根据loginRequest从数据库中提取
        	// DTO(loginUser):剔除了DO中的敏感字段,用于生成token
          
          // 密码正确 生成JWT_token
          String token = JWTUtil.geneJsonWebToken(loginUser);
      
          return JsonData.buildSuccess(token);
      }
      
    • 登录后,客户端存储了token,网页跳转只需要校验token文章来源地址https://www.toymoban.com/news/detail-583740.html

      //拦截器配置
      @Configuration
      @Slf4j
      public class InterceptorConfig implements WebMvcConfigurer {
      
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
      
              registry.addInterceptor(new LoginInterceptor())
                      // 拦截路径,需要token的接口
                      .addPathPatterns("[拦截url]")
      
                      // 放行路径,不需要token的接口,如注册登录接口等...
                      .excludePathPatterns("[放行url]");
          }
      }
      
      
      // 登录拦截器--进行用户的token校验(用户登录成功后网页跳转)
      @Slf4j
      public class LoginInterceptor implements HandlerInterceptor {
      	//本地线程:在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束。
          public static ThreadLocal<LoginUser> threadLocal = new ThreadLocal<>();
      
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
          	// 放行OPTIONS请求
              if(HttpMethod.OPTIONS.toString().equalsIgnoreCase(request.getMethod())){
                  response.setStatus(HttpStatus.NO_CONTENT.value());
                  return true;
              }
              // 从前端获取token
              String accountToken = request.getHeader("token");
              if(StringUtils.isBlank(accountToken)){
                  accountToken = request.getParameter("token");
              }
      
              if(StringUtils.isNotBlank(accountToken)){
              	// 校验token,获取claims
                  Claims claims = JWTUtil.checkJWT(accountToken);
                  if(claims == null){
                      // 未登录
                      CommonUtil.sendJsonMessage(response, JsonData.buildResult(BizCodeEnum.ACCOUNT_UNLOGIN));
                      return false;
                  }
                  // 获取用户字段信息
                  Long accountNo = Long.parseLong(claims.get("account_no").toString());
                  String headImg = (String) claims.get("head_img");
                  String username = (String) claims.get("username");
                  String mail = (String) claims.get("mail");
                  String phone = (String) claims.get("phone");
                  String auth = (String) claims.get("auth");
      			
      			// LoginUser对象需加@Data@Builder@AllArgsConstructor@NoArgsConstructor
                  LoginUser loginUser = LoginUser.builder()
                          .accountNo(accountNo)
                          .auth(auth)
                          .phone(phone)
                          .headImg(headImg)
                          .mail(mail)
                          .userName(username)
                          .build();
                  //request.setAttribute("loginUser",loginUser);
                  //通过threadlocal
                  threadLocal.set(loginUser);
                  return true;
              }
              
              return false;
          }
      
          @Override
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
      
          }
      
          @Override
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      
          }
      }
      

到了这里,关于剖析JWT,及其使用案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WebSocket 协议及其使用案例

    WebSocket 协议是一种用于实时通信、全双工的网络协议。它运行在传输层之上,通常基于 TCP 连接。相较于传统的 HTTP 协议,WebSocket 协议能够在单个连接上进行 双向通信 ,实现 数据的实时交互 ,因此在实时性较高的应用中表现得尤为出色。 WebSocket 协议是一种允许服务器和客

    2024年02月10日
    浏览(42)
  • 深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计

    认证和授权是安全验证中的两个重要概念。认证是确认身份的过程,用于建立双方之间的信任关系。只有在认证成功的情况下,双方才可以进行后续的授权操作。授权则是在认证的基础上,确定用户或系统对资源的访问权限。 在设计一个权限认证框架时,可以考虑以下原则:

    2024年02月12日
    浏览(37)
  • Pixar、Adobe 和苹果等成立 OpenUSD 联盟推行 3D 内容开放标准

    导读 Pixar、Adobe、Apple、Autodesk 与 NVIDIA 联手 Linux 基金会旗下的联合开发基金会(JDF)宣布建立 OpenUSD 联盟(AOUSD)以推行 Pixar 创建的通用场景描述技术的标准化、开发、进化和发展。 联盟寻求通过推进开放式通用场景描述 (OpenUSD) 功能,使 3D 生态系统标准化。 联盟将通过

    2024年02月10日
    浏览(33)
  • 手写一个防抖节流函数及其使用场景

      防抖和节流是性能优化手段 什么是防抖? 防抖:单位时间内,频繁触发事件,只执行最后一次。 防抖的主要应用场景: 搜索框搜索输入。只需用户最后一次输入完,再发送请求 手机号、邮箱验证输入检测 什么是节流? 节流:单位时间内,频繁触发事件,只执行一次。

    2024年02月09日
    浏览(42)
  • JWT安全及案例实战

    越权与逻辑漏洞 Web漏洞点只有一个入口:HTTP Cookie存放在浏览器中。 cookie是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。 cookie由服务器生成,发送给浏览器,浏览器把cookie以k,v形式保存到某个目录下的文本文件

    2024年02月07日
    浏览(30)
  • JWT 安全及案例实战

    ​ cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的

    2024年02月07日
    浏览(35)
  • AI 对齐:深入剖析人工智能伦理和技术标准

    在当今快速发展的人工智能时代,AI 对齐(Artificial Intelligence Alignment)逐渐成为了研究和讨论的热点话题。AI 对齐是指确保人工智能系统的行为与人类价值观和期望保持一致,并能够在面对未明确指令时作出符合人类伦理和利益的决策。此话题不仅关乎技术本身,更触及伦理

    2024年02月21日
    浏览(79)
  • 什么是API密钥及其安全使用指南?

    应用编程接口(API)密钥是应用编程接口用来识别调用应用程序或用户的唯一代码。API密钥用于追踪和控制API的使用者及其使用方式,并验证和授权应用程序,其运作原理与用户名和密码相似。 API密钥以单一密钥或一组多个密钥的形式出现。用户应该遵循最佳实践,改善整体安

    2024年04月22日
    浏览(39)
  • springboot+jwt令牌简单登录案例

    JSON Web Token (JWT)是⼀个开放标准(RFC 7519),它定义了⼀种紧凑的、⾃包含的⽅式,⽤于 作为JSON对象在各⽅之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。 1.1 什么时候应该⽤JWT? Authorization (授权) : 这是使⽤JWT的最常⻅场景。⼀旦⽤⼾登录,后续每个请

    2024年02月01日
    浏览(41)
  • 【Linux】什么是.bashrc,以及其使用方法

    经常在配置linux各种环境的时候,遇到对bashrc的配置。当时也只是机械地跟着教程,一步步输入指令;遇到的次数多了,想知道.bashrc究竟是何方神圣。于是整理了下其主要功能以及使用方法。 .bashrc,属于一种系统隐藏文件,常常可见于 macOS 或者主流的 Linux 发行版。如果你

    2024年03月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包