springboot整合JWT

一、JWT介绍

JSON Web token简称JWT, 是用于对应用程序上的用户进行身份验证的标记。也就是说, 使用 JWTS 的应用程序不再需要保存有关其用户的 cookie 或其他session数据。此特性便于可伸缩性, 同时保证应用程序的安全。

在身份验证过程中, 当用户使用其凭据成功登录时, 将返回 JSON Web token, 并且必须在本地保存 (通常在本地存储中)。每当用户要访问受保护的路由或资源 (端点) 时, 用户代理(user agent)必须连同请求一起发送 JWT, 通常在授权标头中使用Bearer schema。后端服务器接收到带有 JWT 的请求时, 首先要做的是验证token。

1.JWT的格式

JWT就是一个字符串,经过加密处理与校验处理的字符串,形式为:A.B.C,第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

A由JWT头部信息header加密得到

B由JWT用到的身份验证信息json数据加密得到

C由A和B加密得到,是校验部分

2.怎样使用token?

可以放到HTTP请求的请求头中,通常是Authorization字段。

3.流程图

二、java代码实现

springboot经典的四个步骤1.改pom2.写yml/properties3.启动类4.代码

1.maven依赖

   <dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.1</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

2.配置application.properties

没用这个里面的

server.port=8087
# 要加密的明文
jwt.secret=hand2020
# tocken 过期时间,单位秒
jwt.expire=300

3.启动类

这里选择使用@ServletComponentScan,是因为在Filter类用@component和@configuration会导致

@WebFilter(urlPatterns = “/testToken”, filterName = “jwtFilter”) url失效变成拦截所有

package com.example.bootjwt;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication
@ServletComponentScan //这里是将filter扫描加载进spring容器
public class BootJwtApplication {public static void main(String[] args) {SpringApplication.run(BootJwtApplication.class, args);}}

4.实现代码

这里主要是做一个简单的demo验证,有三个类JwtController、CreatToken、JwtFilter。

JwtController:用来接收rest请求。

JwtUtil:用来生成token,解密token,验证token

JwtFilter:用来拦截请求对http请求中携带的token进行验证

JwtController

package com.example.bootjwt.controller;import com.example.bootjwt.Util.JwtUtil;
import com.example.bootjwt.domain.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@RestController
public class JwtController {@PostMapping("/get")public String creatToken2(){User user = new User();user.setId("1");user.setUsername("hand2020");user.setPassword("123456");return JwtUtil.createJWT(40000,user);}@PostMapping("/test")public String testToken2(HttpServletRequest request, HttpServletResponse response){String token= request.getHeader("Authorization");User user = new User();user.setId("1");user.setUsername("hand2020");user.setPassword("123456");if (JwtUtil.isVerify(token,user)){return "success";}return "fail";}
}

JwtUtil

这里我是在配置文件中读需要加密的明文,和过期时间。也可以在controller里处理参数设置。

package com.example.bootjwt.Util;import com.example.bootjwt.domain.User;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;public class JwtUtil {//    @Value("${jwt.secret}")
//    private static String key;/*** 用户登录成功后生成Jwt* 使用Hs256算法  私匙使用用户密码** @param ttlMillis jwt过期时间* @param user      登录成功的user对象* @return*/public static String createJWT(long ttlMillis, User user) {//指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;//生成JWT的时间long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);//创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)Map<String, Object> claims = new HashMap<String, Object>();claims.put("id", user.getId());claims.put("username", user.getUsername());claims.put("password", user.getPassword());//生成签名的时候使用的秘钥secret,这个方法本地封装了的,一般可以从本地配置文件中读取,切记这个秘钥不能外露哦。它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。String key = user.getPassword();//生成签发人String subject = user.getUsername();//下面就是在为payload添加各种标准声明和私有声明了//这里其实就是new一个JwtBuilder,设置jwt的bodyJwtBuilder builder = Jwts.builder()//如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的.setClaims(claims)//设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。.setId(UUID.randomUUID().toString())//iat: jwt的签发时间.setIssuedAt(now)//代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。.setSubject(subject)//设置签名使用的签名算法和签名使用的秘钥.signWith(signatureAlgorithm, key);if (ttlMillis >= 0) {long expMillis = nowMillis + ttlMillis;Date exp = new Date(expMillis);//设置过期时间builder.setExpiration(exp);}return builder.compact();}/*** Token的解密* @param token 加密后的token* @param user  用户的对象* @return*/public static Claims parseJWT(String token, User user) {//签名秘钥,和生成的签名的秘钥一模一样String key = user.getPassword();//得到DefaultJwtParserClaims claims = Jwts.parser()//设置签名的秘钥.setSigningKey(key)//设置需要解析的jwt.parseClaimsJws(token).getBody();return claims;}/*** 校验token* 在这里可以使用官方的校验,我这里校验的是token中携带的密码于数据库一致的话就校验通过* @param token* @param user* @return*/public static Boolean isVerify(String token, User user) {//签名秘钥,和生成的签名的秘钥一模一样String key = user.getPassword();//Jwts.parser在执行parseClaimsJws(token)时如果token时间过期会抛出ExpiredJwtException异常try {//得到DefaultJwtParserClaims claims = Jwts.parser()//设置签名的秘钥.setSigningKey(key)//设置需要解析的jwt.parseClaimsJws(token).getBody();if (claims.get("password").equals(user.getPassword())) {return true;}}catch (ExpiredJwtException e){e.printStackTrace();}return false;}}

JwtFilter

过滤器是通过实现Filter接口,注意@WebFilter相当于xml配置,但是需要在启动类上注解

@ServletComponentScan,将JwtFilter加入到spring容器中。

在JwtFilter类上注解@component或@configuration会导致@WebFilter失效从而拦截所有请求

目前这个没用到,直接在controller里做了判断,这个是后续业务需求的demo

package com.example.bootjwt;import com.example.bootjwt.Util.JwtUtil;
import com.example.bootjwt.domain.User;
import org.springframework.beans.factory.annotation.Autowired;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = "/testToken", filterName = "jwtFilter")
public class JwtFilter implements Filter {@Autowiredprivate CreatToken creatToken;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;response.setCharacterEncoding("UTF-8");response.setContentType("application/json; charset=utf-8");response.setHeader("Access-Control-Allow-Origin", "*");String token= request.getHeader("Authorization");User user = new User();user.setId("1");user.setUsername("hand2020");user.setPassword("123456");boolean flag = JwtUtil.isVerify(token,user);if (flag){filterChain.doFilter(servletRequest,servletResponse);}else {System.out.println("失败。。。。。。。。");response.getWriter().write("失败。。。。。。。。");}}@Overridepublic void destroy() {}
}

##三、 测试效果
由于没有写前端代码,就用postman模拟请求

1.浏览器发送请求获取token

http://localhost:8087/get

2.将token放入请求头中请求

注意将上次请求获得的token放入请求头内(注意不要过太长时间因为token设置了40秒过期)http://localhost:8087/test

token超时:

总结

这个springboot整合jwt只是一个很简单的demo,并不是真正业务中使用方式。后面我会写一个单点登录的例子,会用到jwt。现在这里做一个入门练习。

spring boot jwt_springboot整合JWT相关推荐

  1. Spring Security OAuth2整合JWT

    文章目录 1. Spring Security 与 OAuth2 2. Spring Security OAuth2的配置和使用 ①:引入依赖 ②:配置 spring security ③:配置授权服 ...

  2. JWT实战 Spring Security Oauth2整合JWT 整合SSO单点登录

    文章目录 一.JWT 1.1 什么是JWT 1.2 JWT组成 头部(header) 载荷(payload) 签名(signature) 如何应用 1.3 JJWT 快速开始 创建token toke ...

  3. Spring Boot快速整合Shiro

    文章目录 Spring Boot快速整合Shiro 1.创建Demo 2.Shiro实现登陆拦截 3.Shiro实现用户认证 4.Shiro整合Mybatis-Plus 5.Shiro整合MD5盐值加 ...

  4. spring boot 学习(二)spring boot 框架整合 thymeleaf

    spring boot 框架整合 thymeleaf spring boot 的官方文档中建议开发者使用模板引擎,避免使用 JSP.因为若一定要使用 JSP 将无法使用. 注意:本文主要参考学习了大神 ...

  5. 关于Spring Boot WebSocket整合以及nginx配置详解

    这篇文章主要给大家介绍了关于Spring Boot WebSocket整合以及nginx配置的相关资料,文中通过示例代码给大家介绍的非常详细,相信对大家的学习或者工作具有一定的参考学习价值,需要的朋友 ...

  6. Spring Boot 应用系列 5 -- Spring Boot 2 整合logback

    上一篇我们梳理了Spring Boot 2 整合log4j2的配置过程,其中讲到了Spring Boot 2原装适配logback,并且在非异步环境下logback和log4j2的性能差别不大,所以对 ...

  7. Spring boot Mybatis 整合(注解版)

    之前写过一篇关于springboot 与 mybatis整合的博文,使用了一段时间spring-data-jpa,发现那种方式真的是太爽了,mybatis的xml的映射配置总觉得有点麻烦.接口定义和映 ...

  8. Spring boot Mybatis 整合(完整版)

    Spring boot Mybatis 整合(完整版) 更多干货 SpringBoot系列目录 正题 本项目使用的环境: 开发工具:Intellij IDEA 2017.1.3 springboot: ...

  9. Spring boot Mybatis 整合

    PS: 参考博客 PS: spring boot配置mybatis和事务管理 PS: Spring boot Mybatis 整合(完整版)   这篇博客里用到了怎样 生成 mybatis 插件来写程 ...

最新文章

  1. 深入理解Java虚拟机(类加载机制)
  2. Maven-学习笔记01【基础-Maven基本概念】
  3. LiveVideoStackCon讲师热身分享 ( 十二 ) —— 微博短视频高并发架构
  4. rabbitmq topic 收不到数据_RabbitMQ和Kafka到底怎么选?
  5. mysql分页是物理分页_学习MySQL:什么是分页
  6. delphi编程来记录QQ的聊天记录
  7. 【书山有路】互联网+:从IT到DT 读书笔记
  8. Curvy Little Bottles-二分和积分
  9. 公式计算机实现,数学公式的计算机表达(精选).doc
  10. Ubuntu 快捷截图
  11. numpy 随机生成矩阵
  12. NepCTF2022
  13. html右边显示不全,显示器右边显示不全怎么办
  14. 腾讯云服务器+RAKSmart国内外服务器使用记录
  15. 参考线--深入了解字体
  16. mybatis拦截器实现update之前根据pk字段校验数据有效性
  17. 一个c加一个g是什么牌子_C和G打头的手表都有哪些?
  18. 视频点播服务器性能,EasyDSS视频点播服务器实现的多码率点播功能的说明
  19. php的 post get
  20. SPSS下载安装JDK和tomcat,并配置好相关的环境变量!!

热门文章

  1. 【译】怎样处理 Safari 移动端对图片资源的限制
  2. python入门(7)Python程序的风格
  3. linux自学_shell脚本for详解
  4. objective-c 语法快速过(4)
  5. 2014年5月生日会
  6. IOS libxml/tree.h file not found 解决方案
  7. 怎样定义和引用一维数组,二维数组
  8. 如何在CISCO PIX上实现×××步骤?
  9. 轻松学习 Flex 布局的小游戏
  10. 人工智能如何有效地运用于自然语言处理