专栏首页小怪聊职场安全|Java中使用JWT生成Token进行接口鉴权实现

安全|Java中使用JWT生成Token进行接口鉴权实现

先介绍下利用JWT进行鉴权的思路: 1、用户发起登录请求。 2、服务端创建一个加密后的JWT信息,作为Token返回。 3、在后续请求中JWT信息作为请求头,发给服务端。 4、服务端拿到JWT之后进行解密,正确解密表示此次请求合法,验证通过;解密失败说明Token无效或者已过期。

流程图如下:

网图

一、用户发起登录请求

欢迎大家访问www.fota.com

二、服务端创建一个加密后的JWT信息,作为Token返回

1、用户登录之后把生成的Token返回给前端

@Authorization
@ResponseBody
@GetMapping("user/auth")
public Result getUserSecurityInfo(HttpServletRequest request) {
   try {
       UserDTO userDTO = ...
       UserVO userVO = new UserVO();
       //这里调用创建JWT信息的方法
       userVO.setToken(TokenUtil.createJWT(String.valueOf(userDTO.getId())));
       return Result.success(userVO);
   } catch (Exception e) {
       return Result.fail(ErrorEnum.SYSTEM_ERROR);
   }
}

2、创建JWT,Generate Tokens

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import io.jsonwebtoken.*;
import java.util.Date;    
 
//Sample method to construct a JWT
private String createJWT(String id, String issuer, String subject, long ttlMillis) {
 
    //The JWT signature algorithm we will be using to sign the token
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
 
    long nowMillis = System.currentTimeMillis();
    Date now = new Date(nowMillis);
 
    //We will sign our JWT with our ApiKey secret
    byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(apiKey.getSecret());
    Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
 
    //Let's set the JWT Claims
    JwtBuilder builder = Jwts.builder().setId(id)
                                .setIssuedAt(now)
                                .setSubject(subject)
                                .setIssuer(issuer)
                                .signWith(signatureAlgorithm, signingKey);
 
    //if it has been specified, let's add the expiration
    if (ttlMillis >= 0) {
    long expMillis = nowMillis + ttlMillis;
        Date exp = new Date(expMillis);
        builder.setExpiration(exp);
    }
 
    //Builds the JWT and serializes it to a compact, URL-safe string
    return builder.compact();
}

3、作为Token返回

看后面有个Token

三、在后续请求中JWT信息作为请求头,发给服务端

缺一个图,马上补

四、服务端拿到JWT之后进行解密,正确解密表示此次请求合法,验证通过;解密失败说明Token无效或者已过期。

1、在拦截器中读取这个Header里面的Token值

@Slf4j
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    private boolean chechToken(HttpServletRequest request, HttpServletResponse response) throws IOException{
        Long userId = ...;

        if (!TokenUtil.parseJWT(request.getHeader("Authorization"), String.valueOf(userId))){
            response.setContentType("text/html;charset=GBK");
            response.setCharacterEncoding("GBK");
            response.setStatus(403);
            response.getWriter().print("<font size=6 color=red>对不起,您的请求非法,系统拒绝响应!</font>");
            return false;
        } else{
            return true;
        }
    }
}

2、拿到之后进行解密校验 Decode and Verify Tokens

import javax.xml.bind.DatatypeConverter;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Claims;
 
//Sample method to validate and read the JWT
private void parseJWT(String jwt) {
    //This line will throw an exception if it is not a signed JWS (as expected)
    Claims claims = Jwts.parser()         
       .setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret()))
       .parseClaimsJws(jwt).getBody();
    System.out.println("ID: " + claims.getId());
    System.out.println("Subject: " + claims.getSubject());
    System.out.println("Issuer: " + claims.getIssuer());
    System.out.println("Expiration: " + claims.getExpiration());
}

五、总结

大家知道,我之前做过爬虫,实际这种思路在微博做反爬时也用过,看过我之前文章的同学应该知道。 好了,最后欢迎大家访问www.fota.com体验我们的产品。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一份超详细的Java问题排查工具单

    平时的工作中经常碰到很多疑难问题的处理,在解决问题的同时,有一些工具起到了相当大的作用,在此书写下来,一是作为笔记,可以让自己后续忘记了可快速翻阅,二是分享,希...

    lyb-geek
  • 干货|Python 获取网易云音乐热门评论

    最近在研究文本挖掘相关的内容,所谓巧妇难为无米之炊,要想进行文本分析,首先得到有文本吧。获取文本的方式有很多,比如从网上下载现成的文本文档,或者通过第三方提供的...

    fishexpert
  • SpringBoot核心技术:你了解Actuator开放指定监控节点吗?

    之前章节SpringBoot核心技术:探究Actuator的默认开放节点 & 详细健康状态讲解了spring-boot-actuator默认开放的节点以及如何修...

    恒宇少年
  • 单例模式 创建型 设计模式(六)

    可以借助于全局变量,但是类就在那里,你不能防止实例化多个对象,可能一不小心谁就创建了一个对象

    noteless
  • 2018-11-20 老码农教你在 StackOverflow 上谈笑风生

    作为一个高大上的码农,你肯定用到过 StackOverflow,必须的。会有人否定这个断言么?那他恐怕不是真正的码农,或者说还没入门。StackOverflow...

    Albert陈凯
  • SNMP学习笔记之SNMP4J介绍(Java)

      SNMP4J是一个用Java来实现SNMP(简单网络管理协议)协议的开源项目.它支持以命令行的形式进行管理与响应。SNMP4J是纯面向对象设计与SNMP++...

    Jetpropelledsnake21
  • 北京美团程序员3万工资高不高?

    讲一个真实的故事,认识一个在美团工作的程序员,是个女生是从百度直接跳槽过去的,在里面担任技术主管,在北京房价还不是最疯狂的时候买了一套差不多300多万的房子,在...

    程序员互动联盟
  • 代码里注释写太多,会挨打吗?

    前几天,有个同行朋友在我的微信上留言,问我项目代码里注释写太多会挨打吗?顺手还给我甩了一张截图,上面密密麻麻的全是手工注释。

    闰土大叔
  • 【1024程序员节】致敬所有程序员

    2002年,俄罗斯程序员Valentin Balt收集签名,向俄罗斯联邦政府请愿将9月13日设定为程序员节。2009年9月11日,俄罗斯总统梅德韦杰夫在节日安排...

    java思维导图
  • C 语言:我不是针对谁,我是说在座的都是乐色

    从上世纪七十年代开始,许多编程语言都曾受到程序员的青睐。尽管这些语言很好、很有用,但从高级语言开始学习的人在编程知识方面都有许多遗漏。

    老九君

扫码关注云+社区

领取腾讯云代金券