springboot中整合JWT Token
1、pom.xml中引入
<!--jwt token--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
2、application.yml中配置
jwt: # 加密密钥 secret: jellymilk # token有效时长 1小时:3600 1天:86400 expire: 3600 # header 名称 header: Authorization #发行人 issuer: cbyzs #忽略token验证的 请求 ignores: - /login/token - /static/**3、JwtProperties属性配置bean
import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.List; /** * jwt配置参数信息 */ @Getter @Setter @ConfigurationProperties(prefix = "jwt") public class JwtProperties { private String secret;//加密密钥 private Long expire; // token有效期 秒 private String header;// token 采用的http头,一般使用: Authorization private String issuer;//发行人 private List<String> ignores; //忽略token的页面 }
import java.lang.annotation.*; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface JwtTokenIgnore { }4、Token的web拦截器
import cn.cbyzs.ssdemo.common.exception.BusinessException; import cn.hutool.core.util.StrUtil; import io.jsonwebtoken.Claims; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.util.Date; import java.util.List; @Component public class JwtTokenInterceptor extends HandlerInterceptorAdapter { @Autowired private JwtTokenUtil jwtTokenUtil; private AntPathMatcher antPathMatcher = new AntPathMatcher(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 如果不是映射到方法直接通过 if(!(handler instanceof HandlerMethod)){ return true; } //controller的方法上标记了 JwtTokenIgnore 注解的方法,直接放行 HandlerMethod handlerMethod=(HandlerMethod)handler; Method method=handlerMethod.getMethod(); if(method.isAnnotationPresent(JwtTokenIgnore.class)){ return true;//放行 } JwtProperties props= jwtTokenUtil.getJwtProperties(); List<String> ignores =props.getIgnores(); String contextPath=request.getContextPath(); String uri=request.getRequestURI(); String path=uri.replaceFirst(contextPath, "").replaceAll("/+", "/"); //ignores 忽略的请求 ,放行 for (String pattern : ignores) { if (antPathMatcher.match(pattern, path)) { return true;//放行 } } String token = request.getHeader(props.getHeader()); if(StrUtil.isEmpty(token)){ throw new BusinessException(3000,"token不能为空"); } Claims claims = jwtTokenUtil.parseJWT(token); if(claims.getExpiration().before(new Date())){ throw new BusinessException(3000,"token已过期,请重新获取"); } request.setAttribute("identityId", claims.getSubject());//设置用户凭证id return true; } }WebConfig 配置,添加注册拦截器
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private JwtTokenInterceptor tokenInterceptor ; /** * 配置全站允许CORS跨域访问 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") //允许的来源域 如http://www.demo.com .allowedMethods("GET", "POST","PUT","DELETE","PATCH") .allowCredentials(false).maxAge(3600); } /** * 配置web拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(tokenInterceptor) .addPathPatterns("/**"); } }5、JwtTokenUtil 工具bean
import cn.cbyzs.ssdemo.common.exception.BusinessException; import cn.hutool.core.util.StrUtil; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Base64; import java.util.Date; @Configuration @EnableConfigurationProperties(JwtProperties.class) @Slf4j public class JwtTokenUtil { @Autowired private JwtProperties jwtProperties; public JwtProperties getJwtProperties() { return jwtProperties; } public String getSecretKey(){ return Base64.getEncoder().encodeToString(jwtProperties.getSecret().getBytes()); } /** * 生成token * @param subject 一般为用户名 * @return */ public String createToken (String subject){ String secret =jwtProperties.getSecret();//密钥 long expire= jwtProperties.getExpire();//过期失效 String issuer = jwtProperties.getIssuer();//发行人 Date nowDate = new Date(); Date expireDate = new Date(nowDate.getTime() + expire * 1000);//过期时间 return Jwts.builder() .setHeaderParam("typ", "JWT") .setSubject(subject)//主题 .setIssuer(issuer)//发行人 .setIssuedAt(nowDate) //发行时间 .setExpiration(expireDate)//过期时间 //.setClaims() .signWith(SignatureAlgorithm.HS256, getSecretKey())// 签名部分 .compact(); } /** * 获取token中注册信息 (body信息) * @param token * @return */ public Claims parseJWT (String token) { try { if(StrUtil.isEmpty(token)){ throw new BusinessException(3000,"token不能为空"); } String secret =getSecretKey();//密钥 return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); }catch (Exception e){ log.error(e.getMessage(),e); throw new BusinessException(3000,"验证token失败"); } } /** * 从http请求中获取http的token头 * @return */ public String getHttpToken(){ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token= request.getHeader(jwtProperties.getHeader()); return token; } public Claims getTokenClaims(){ String token = getHttpToken(); return parseJWT(token); } public String getTokenClaimsSubject(){ String token = getHttpToken(); Claims claims= parseJWT(token); return claims.getSubject(); } }6、LoginController.java 登录token、刷新token、从token中获取用户信息
import cn.cbyzs.ssdemo.common.RetMsg; import cn.cbyzs.ssdemo.common.jwt.JwtTokenUtil; import cn.cbyzs.ssdemo.user.model.User; import cn.cbyzs.ssdemo.user.service.LoginService; import io.jsonwebtoken.Claims; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/login") public class LoginController { @Autowired private LoginService loginService; @Autowired private JwtTokenUtil jwtTokenUtil; /** * 登录获取token * @param username 用户名 * @param password 密码 * @return */ @RequestMapping("/token") public RetMsg token(String username,String password){ User user= loginService.login(username,password); if(user!=null){ //说明登录成功 String token= jwtTokenUtil.createToken(user.getUsername()); Claims claims= jwtTokenUtil.parseJWT(token);//jwt主体 Map<String,Object> data=new HashMap<>(); data.put("user",user); data.put("token",token); data.put("expire",claims.getExpiration()); return RetMsg.success(data);//下发token和用户信息 } return RetMsg.failure("用户登录失败"); } /** * 刷新token 获取新的token * @return */ @RequestMapping("/refreshToken") public RetMsg refreshToken(){ String username= jwtTokenUtil.getTokenClaimsSubject(); //生成新的token String newToken = jwtTokenUtil.createToken(username); return RetMsg.success(newToken) ; } /** * 获取用户信息,从token中获取到username * @return */ @RequestMapping("/getUserInfo") public RetMsg getUserInfo(){ String username= jwtTokenUtil.getTokenClaimsSubject(); User user= loginService.findUserByUsername(username); return RetMsg.success(user); } }
~~
上一篇:centos7安装mysql8
Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1