2020-11-24 Java的JJWT实现JWT

1,什么是JJWT

JJWT是一个提供端到端的JWT创建和验证的Java库
token的创建

引入依赖

    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.6.0</version>
    </dependency>

创建类CreateJwtTest,用于生成token` public class CreateJwtTest {

  public static void main(String[] args) {
    JwtBuilder builder= Jwts.builder().setId("888") .setSubject("小白")
              .setIssuedAt(new Date())//设置签发时间
              .signWith(SignatureAlgorithm.HS256,"xiaocai");//设置签名秘钥
      System.out.println( builder.compact() ); 
      // eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1MjM0MTM0NTh9.gq0JcOM_qCNqU_sd_IrRytaNenesPmqAIhQpYXHZk

        } 
  }

// 再次运行,会发现每次运行的结果是不一样的,因为我们的载荷中包含了时间。

Token的解析

 public class ParseJwtTest {
      public static void main(String[] args) {
          String
  token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiO
  jE1MjM0MTM0NTh9.gq0J‐cOM_qCNqU_s‐d_IrRytaNenesPmqAIhQpYXHZk";
          Claims claims =
  Jwts.parser().setSigningKey("xiaocai").parseClaimsJws(token).getBody();
          System.out.println("id:"+claims.getId());
          System.out.println("subject:"+claims.getSubject());
          System.out.println("IssuedAt:"+claims.getIssuedAt());
    }
}

token过期校验

public class CreateJwtTest2 {
      public static void main(String[] args) {
    //为了方便测试,我们将过期时间设置为1分钟
    long now = System.currentTimeMillis();//当前时间 
    long exp = now + 1000*60;//过期时间为1分钟 
    JwtBuilder builder= Jwts.builder().setId("888")
        .setSubject("小白")
        .setIssuedAt(new Date())
        .signWith(SignatureAlgorithm.HS256,"xiaocai") 
        .setExpiration(new Date(exp));//设置过期时间
          System.out.println( builder.compact() );
      }
}
public class ParseJwtTest {
      public static void main(String[] args) {
        String compactJws="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1MjM0MTY1NjksImV4cCI6MTUyMzQxNjYyOX0.Tk91b6mvyjpKcldkic8DgXz0zsPFF
  nRgTgkgcAsa9cc";
          Claims claims = Jwts.parser()
                            .setSigningKey("xiaocai")
                            .parseClaimsJws(compactJws).getBody();
          System.out.println("id:"+claims.getId());
          System.out.println("subject:"+claims.getSubject());
          SimpleDateFormat sdf=new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss");
System.out.println("签发时间:"+sdf.format(claims.getIssuedAt()));
System.out.println("过期时间:"+sdf.format(claims.getExpiration()));
System.out.println("当前时间:"+sdf.format(new Date()) );
     }
}

自定义claims

public class CreateJwtTest3 {
      public static void main(String[] args) {
//为了方便测试,我们将过期时间设置为1分钟
long now = System.currentTimeMillis();//当前时间 
long exp = now + 1000*60;//过期时间为1分钟 
JwtBuilder builder= Jwts.builder().setId("888")
.setSubject("小白")
.setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256,"xiaocai") .setExpiration(new Date(exp)) .claim("roles","admin") .claim("logo","logo.png");
          System.out.println( builder.compact() );
      }
}

 public class ParseJwtTest {
      public static void main(String[] args) {
          String
  compactJws="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJp
  YXQiOjE1MjM0MTczMjMsImV4cCI6MTUyMzQxNzM4Mywicm9sZXMiOiJhZG1pbiIsImxvZ28iO
  iJsb2dvLnBuZyJ9.b11p4g4rE94rqFhcfzdJTPCORikqP_1zJ1MP8KihYTQ";
          Claims claims =
  Jwts.parser().setSigningKey("xiaocai").parseClaimsJws(compactJws).getBody();
          System.out.println("id:"+claims.getId());
          System.out.println("subject:"+claims.getSubject());
          System.out.println("roles:"+claims.get("roles"));
          System.out.println("logo:"+claims.get("logo"));
          SimpleDateFormat sdf=new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss");
System.out.println("签发时间:"+sdf.format(claims.getIssuedAt()));
System.out.println("过期时 间:"+sdf.format(claims.getExpiration()));
System.out.println("当前时间:"+sdf.format(new Date()) );
    }
}
JWT工具类

@Data
public class JwtUtil {

    private String key; //密钥加盐

    private long ttl;   //过期时间

    /**
     * 生成JWT
     */
    public String createJWT(String id, String subject, String role) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        JwtBuilder builder = Jwts.builder().setId(id)
                .setSubject(subject)
                .setIssuedAt(now)
                .signWith(SignatureAlgorithm.HS256, key).claim("role", role);
        if (ttl > 0) {
            builder.setExpiration(new Date(nowMillis + ttl));
        }
        return builder.compact();
    }

    /**
     * 解析JWT
     */
    public Claims parseJWT(String jwtStr) {
        return Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(jwtStr)
                .getBody();
    }
}


添加配置

jwt:
  config:
    key: littledonkey
    ttl: 3600000


签发token

        //判断是否密码是否正确
        Admin loginAdmin = adminService.login(admin);
        if (loginAdmin == null) {
            return new Result(false, StatusCode.LOGINERROR, "登陆失败");
        }
        //签发token
        String token = jwtUtil.createJWT(admin.getId(), admin.getLoginname(), "admin");
        HashMap<String, String> map = new HashMap<>();
        map.put("token", token);
        map.put("role", "admin");
        return new Result(true, StatusCode.OK, "登陆成功", map);

添加拦截器

@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求头(如果有此请求头,表示token已经签发)
        String header = request.getHeader("tokenHeader");
        if (header != null || !"".equals(header)) {
            //解析请求头(防止伪造token,token内容以"token "作为开头)
            if (header.startsWith("token ")) {
                try {
                    Claims claims = jwtUtil.parseJWT(header.substring(6));
                    String role = (String) claims.get("role");
                    //为具有相关权限的用户添加权限到request域中
                    if ("admin".equals(role)) {
                        //拿到"admin_token"头信息,表示当前角色是admin
                        request.setAttribute("admin_token", header.substring(6));
                    }
                    if ("user".equals(role)) {
                        //拿到"user_token"头信息,表示当前角色是user
                        request.setAttribute("user_token", header.substring(6));
                    }
                } catch (Exception e) {
                    throw new RuntimeException("令牌不正确");
                }
            }
        }
        //所有请求都通过,具体权限在service层判断
        return true;
    }
}


注册拦截器

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
    @Autowired
    private TokenInterceptor tokenInterceptor;

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/login/**");
    }
}


service层验证

    public void deleteById(String id) {
        String admin_token = (String) request.getAttribute("admin_token");
        if(admin_token == null || "".equals(admin_token)){
            throw new RuntimeException("权限不足");
        }
        adminDao.deleteById(id);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值