4.0.0
org.springframework.boot
spring-boot-starter-parent
2.6.4
com.example
jwtdemo
0.0.1-SNAPSHOT
jwtdemo
jwtdemo
1.8
org.springframework.boot
spring-boot-starter
com.auth0
java-jwt
3.10.3
org.projectlombok
lombok
com.alibaba
fastjson
1.2.30
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-maven-plugin
paketobuildpacks/builder-jammy-base:latest
server:
port: 8085
#生成token需要的参数
com:
example:
type: JWT
alg: HS256
secret: dsij787eawGa7wa!dsadlwdasd
expireTime: 6000000
package com.example.jwtdemo.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* @className:@JWTConfig
* @Description:TODO
* @Author:
* @Version:1.0
**/
@Configuration
@Data
public class JWTConfig {
@Value("${com.example.type}")
private String type;
@Value("${com.example.alg}")
private String alg;
@Value("${com.example.secret}")
private String secret;
@Value("${com.example.expireTime}")
private Integer expireTime;
}
package com.example.jwtdemo.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.example.jwtdemo.config.JWTConfig;
import com.example.jwtdemo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @className:@TokenUtil
* @Description: Token主要有三部分组成 头部+负载+签名
* @Author:
* @Version:1.0
**/
@Component
public class TokenUtil {
@Autowired
private JWTConfig jwtConfig;
public String createToken(User user){
Map headers = new HashMap<>();
headers.put("type",jwtConfig.getType());
headers.put("alg",jwtConfig.getAlg());
Algorithm algorithm = Algorithm.HMAC256(jwtConfig.getSecret());
//设置过期时间
Date expireDate = new Date(System.currentTimeMillis()+jwtConfig.getExpireTime());
String token = JWT.create()
.withClaim("id",user.getId())
.withClaim("username",user.getUsername())
.withClaim("roleId",user.getRoleId())
.withIssuer("admin")
.withNotBefore(new Date())
.withExpiresAt(expireDate)
.sign(algorithm);
return token;
}
}
package com.example.jwtdemo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.jwtdemo.model.User;
import com.example.jwtdemo.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* @className:@LoginConroller
* @Description:TODO
* @Author:
* @Version:1.0
**/
@RestController
@RequestMapping("/")
public class LoginConroller {
@Autowired
private TokenUtil tokenUtil;
@PostMapping("/login")
public String login(@RequestBody @Validated JSONObject jsonObject){
String username = jsonObject.getString("username");
String password = jsonObject.getString("password");
User u = new User();
if (password.equals("admin")){
u.setRoleId(1);
u.setId(1);
u.setUsername("username11");
return tokenUtil.createToken(u);
}else {
return "error";
}
}
@GetMapping("/getUser")
public String getUser(Integer id){
return "success";
}
}
package com.example.jwtdemo.filter;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.jwtdemo.config.JWTConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
* @className:@JWTFilter
* @Description:TODO
* @Author:
* @Version:1.0
**/
@Component
@WebFilter(filterName = "jwtFilter",urlPatterns = {"/*"})
public class JWTFilter implements Filter {
private Logger logger = LoggerFactory.getLogger(JWTFilter.class);
@Autowired
private JWTConfig config;
//登录拦截
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
String url = req.getRequestURL().toString();
//指定放开路径
String urls [] ={"/login","/xxx"};
logger.info("url====={}",url);
//是否放行
boolean isFilter = false;
for (String u:urls){
if (url.contains(u)){
isFilter =true;
}
}
//拦截认证
if (!isFilter){
//获取token的值
try {
PrintWriter printWriter =servletResponse.getWriter();
String token = req.getHeader("token");
if (StringUtils.isEmpty(token)){
throw new Exception("token不为空");
}
Algorithm algorithm = Algorithm.HMAC256(config.getSecret());
//验证签名是否正确
DecodedJWT decodedJWT = JWT.require(algorithm).build().verify(token);
//获取jwt中的业务信息
Integer id = decodedJWT.getClaim("id").asInt();
String username = decodedJWT.getClaim("username").asString();
Integer roleId = decodedJWT.getClaim("roleId").asInt();
}catch (Exception e){
//logger.info("签名验证失败,token不正确{}",e.getMessage());
PrintWriter writer = null;
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setContentType("text/html; charset=utf-8");
MapresMap = new HashMap<>();
resMap.put("code",500);
resMap.put("msg","签名失败!");
resMap.put("data",null);
writer = servletResponse.getWriter();
writer.print(resMap);
return ;
}
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
9.总结:名词解释
过滤器:过滤请求路径,除了指定不拦截的路径,其他路径均要拦截,拦截之后,对token进行验签,通过之后,才可访问后端相应路径。
token:token是一个将用户信息合成然后进行签名的一串字符,验签就是类似一个解密的过程,能获取到用户具体的信息。