一、JWT的简介
二、入门案例
第一步:引入依赖
< dependency>
< groupId> com.auth0</ groupId>
< artifactId> java-jwt</ artifactId>
< version> 3.4.0</ version>
</ dependency>
第二步:生成token
package com. yx. jwt ;
import com. auth0. jwt. JWT;
import com. auth0. jwt. algorithms. Algorithm ;
import org. junit. jupiter. api. Test ;
import org. springframework. boot. test. context. SpringBootTest ;
import java. util. Calendar ;
import java. util. HashMap ;
import java. util. Map ;
class JWTDemoApplicationTests {
@Test
void contextLoads ( ) {
Map < String , Object > map = new HashMap < > ( ) ;
Calendar instance = Calendar . getInstance ( ) ;
instance. add ( Calendar . SECOND, 20 ) ;
String token = JWT. create ( )
. withHeader ( map)
. withClaim ( "userId" , 21 )
. withClaim ( "username" , "zhangsan" )
. withExpiresAt ( instance. getTime ( ) )
. sign ( Algorithm . HMAC256 ( "@93!#49&$33" ) ) ;
System . out. println ( token) ;
}
}
第三步:根据令牌和签名解析数据
@Test
public void test ( ) {
JWTVerifier jwtVerifier = JWT. require ( Algorithm . HMAC256 ( "@93!#49&$33" ) ) . build ( ) ;
DecodedJWT verify = jwtVerifier. verify ( "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2ODUxMDcyNTcsInVzZXJJZCI6MjEsInVzZXJuYW1lIjoiemhhbmdzYW4ifQ.JN5Dq_7iUfcr7tQcaHLiCFZMb0Byr7rUkDvNKA_2xf0" ) ;
System . out. println ( verify. getHeader ( ) ) ;
System . out. println ( verify. getClaims ( ) . get ( "userId" ) . asInt ( ) ) ;
System . out. println ( verify. getClaims ( ) . get ( "username" ) . asString ( ) ) ;
System . out. println ( "过期时间" + verify. getExpiresAt ( ) ) ;
}
JWT的工具肋封装
package com. yx. jwt. utils ;
import com. auth0. jwt. JWT;
import com. auth0. jwt. JWTCreator ;
import com. auth0. jwt. JWTVerifier ;
import com. auth0. jwt. algorithms. Algorithm ;
import com. auth0. jwt. exceptions. JWTVerificationException ;
import com. auth0. jwt. interfaces. DecodedJWT ;
import java. util. Calendar ;
import java. util. Map ;
public class JWTUtils {
private static final String SING = "@93!#49&$33" ;
public static String getToken ( Map < String , String > map) {
Calendar instance = Calendar . getInstance ( ) ;
instance. add ( Calendar . DATE, 7 ) ;
JWTCreator. Builder builder = JWT. create ( ) ;
map. forEach ( ( k, v) -> {
builder. withClaim ( k, v) ;
} ) ;
String token = builder. withExpiresAt ( instance. getTime ( ) ) . sign ( Algorithm . HMAC256 ( SING) ) ;
return token;
}
public static void verify ( String token) {
DecodedJWT verify = JWT. require ( Algorithm . HMAC256 ( SING) ) . build ( ) . verify ( token) ;
}
public static DecodedJWT getTokenInfo ( String token) {
DecodedJWT verify = JWT. require ( Algorithm . HMAC256 ( SING) ) . build ( ) . verify ( token) ;
return verify;
}
}
三、结合springboot
第一步:引入依赖
<?xml version="1.0" encoding="UTF-8"?>
< project xmlns = " http://maven.apache.org/POM/4.0.0" xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation= " http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" >
< modelVersion> 4.0.0</ modelVersion>
< parent>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-parent</ artifactId>
< version> 2.7.13-SNAPSHOT</ version>
< relativePath/>
</ parent>
< groupId> com.example</ groupId>
< artifactId> jwt-springboot</ artifactId>
< version> 0.0.1-SNAPSHOT</ version>
< name> jwt-springboot</ name>
< description> jwt-springboot</ description>
< properties>
< java.version> 1.8</ java.version>
</ properties>
< dependencies>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-web</ artifactId>
</ dependency>
< dependency>
< groupId> org.mybatis.spring.boot</ groupId>
< artifactId> mybatis-spring-boot-starter</ artifactId>
< version> 2.2.0</ version>
</ dependency>
< dependency>
< groupId> com.alibaba</ groupId>
< artifactId> druid</ artifactId>
< version> 1.1.19</ version>
</ dependency>
< dependency>
< groupId> mysql</ groupId>
< artifactId> mysql-connector-java</ artifactId>
< version> 8.0.29</ version>
</ dependency>
< dependency>
< groupId> org.projectlombok</ groupId>
< artifactId> lombok</ artifactId>
< optional> true</ optional>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-test</ artifactId>
< scope> test</ scope>
</ dependency>
< dependency>
< groupId> com.auth0</ groupId>
< artifactId> java-jwt</ artifactId>
< version> 3.4.0</ version>
</ dependency>
</ dependencies>
< build>
< plugins>
< plugin>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-maven-plugin</ artifactId>
< configuration>
< excludes>
< exclude>
< groupId> org.projectlombok</ groupId>
< artifactId> lombok</ artifactId>
</ exclude>
</ excludes>
</ configuration>
</ plugin>
</ plugins>
</ build>
< repositories>
< repository>
< id> spring-milestones</ id>
< name> Spring Milestones</ name>
< url> https://repo.spring.io/milestone</ url>
< snapshots>
< enabled> false</ enabled>
</ snapshots>
</ repository>
< repository>
< id> spring-snapshots</ id>
< name> Spring Snapshots</ name>
< url> https://repo.spring.io/snapshot</ url>
< releases>
< enabled> false</ enabled>
</ releases>
</ repository>
</ repositories>
< pluginRepositories>
< pluginRepository>
< id> spring-milestones</ id>
< name> Spring Milestones</ name>
< url> https://repo.spring.io/milestone</ url>
< snapshots>
< enabled> false</ enabled>
</ snapshots>
</ pluginRepository>
< pluginRepository>
< id> spring-snapshots</ id>
< name> Spring Snapshots</ name>
< url> https://repo.spring.io/snapshot</ url>
< releases>
< enabled> false</ enabled>
</ releases>
</ pluginRepository>
</ pluginRepositories>
</ project>
第二步:添加配置项
spring. datasource. type= com. alibaba. druid. pool. DruidDataSource
spring. datasource. driver- class - name= com. mysql. cj. jdbc. Driver
spring. datasource. url= jdbc: mysql: / / localhost: 3306 / jwt? characterEncoding= UTF- 8 & useSSL= false
spring. datasource. username= root
spring. datasource. password= root
mybatis. type- aliases- package = com. example. jwt. entity
mybatis. mapper- locations= classpath: mapper
第三步:添加实体类
package com. example. jwt. entity ;
import lombok. Data ;
import lombok. experimental. Accessors ;
@Data
@Accessors ( chain = true )
public class User {
private Integer id;
private String username;
private String password;
}
第四步:添加持久层
UserDao.java
package com. example. jwt. dao ;
import com. example. jwt. entity. User ;
import org. apache. ibatis. annotations. Mapper ;
@Mapper
public interface UserDAO {
User login ( User user) ;
}
UserDAO.xml
<?xml version="1.0" encoding="UTF-8"?>
<! DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
< mapper namespace = " com.example.jwt.dao.UserDAO" >
< select id = " login" parameterType = " User" resultType = " User" >
select * from user where username = #{username} and password = #{password}
</ select>
</ mapper>
第五步:添加业务层
UserService
package com. example. jwt. service ;
import com. example. jwt. entity. User ;
public interface UserService {
User login ( User user) ;
}
UserServiceImpl
package com. example. jwt. service. impl ;
import com. example. jwt. dao. UserDAO ;
import com. example. jwt. entity. User ;
import com. example. jwt. service. UserService ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. stereotype. Service ;
import org. springframework. transaction. annotation. Propagation ;
import org. springframework. transaction. annotation. Transactional ;
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
@Override
@Transactional ( propagation = Propagation . SUPPORTS)
public User login ( User user) {
User login = userDAO. login ( user) ;
if ( login != null ) {
return login;
}
throw new RuntimeException ( "登录失败~~" ) ;
}
}
第六步:添加拦截器
package com. example. jwt. interceptors ;
import com. auth0. jwt. exceptions. AlgorithmMismatchException ;
import com. auth0. jwt. exceptions. SignatureVerificationException ;
import com. auth0. jwt. exceptions. TokenExpiredException ;
import com. auth0. jwt. interfaces. DecodedJWT ;
import com. example. jwt. utils. JWTUtils ;
import com. fasterxml. jackson. databind. ObjectMapper ;
import org. springframework. web. servlet. HandlerInterceptor ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. util. HashMap ;
import java. util. Map ;
public class JWTInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle ( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Map < String , Object > map = new HashMap < > ( ) ;
String token = request. getHeader ( "token" ) ;
try {
DecodedJWT verify = JWTUtils . verify ( token) ;
return true ;
} catch ( SignatureVerificationException e) {
map. put ( "msg" , "无效签名" ) ;
e. printStackTrace ( ) ;
} catch ( TokenExpiredException e) {
map. put ( "msg" , "token失效" ) ;
e. printStackTrace ( ) ;
} catch ( AlgorithmMismatchException e) {
map. put ( "msg" , "token算法不一致" ) ;
e. printStackTrace ( ) ;
} catch ( Exception e) {
map. put ( "msg" , "token无效!" ) ;
e. printStackTrace ( ) ;
}
map. put ( "state" , false ) ;
String json = new ObjectMapper ( ) . writeValueAsString ( map) ;
response. setContentType ( "application/json;charset=UTF-8" ) ;
response. getWriter ( ) . println ( json) ;
return false ;
}
}
第七步:添加配置类
package com. example. jwt. config ;
import com. example. jwt. interceptors. JWTInterceptor ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. web. servlet. config. annotation. InterceptorRegistry ;
import org. springframework. web. servlet. config. annotation. WebMvcConfigurer ;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors ( InterceptorRegistry registry) {
registry. addInterceptor ( new JWTInterceptor ( ) )
. addPathPatterns ( "/user/test" )
. excludePathPatterns ( "/user/login" ) ;
}
}
第八步:测试