1. 导包
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2. 工具类
package com.springCloud.common.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
@ConfigurationProperties(prefix = "jwt.config")
@Component
@Data
public class JWT {
private String key;
private long expiration;
/**
* 创建 JWT
* @param id 用户的 id 号
* @param subject 用户名
* @param role 用户的角色
* @return JWT 编码.
*/
public String createJWT(String id, String subject, String role) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder jwtBuilder = Jwts.builder()
.setId(id)
.setSubject(subject)
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, key)
.claim("role", role);
if (expiration > 0) {
jwtBuilder.setExpiration(new Date(nowMillis + expiration));
}
return jwtBuilder.compact();
}
/**
* 解析 JWT
* @param jwtString JWT 编码字符串
* @return String
*/
public Claims parseJWT(String jwtString) {
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwtString)
.getBody();
}
}
3. 拦截器
package com.springCloud.user.interceptor;
import com.springCloud.common.util.JWT;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class JwtInterceptor implements HandlerInterceptor {
private JWT jwt;
@Autowired
private JwtInterceptor(JWT jwt) {
this.jwt = jwt;
}
/**
* 如论如何都需要放行, 而拦截需要在操作中去判断.
* login 中 拦截器只需要将请求头中包括 token 的令牌进行解析.
*
* @param request 请求
* @param response 响应
* @param handler 处理
* @return boolean
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 得到请求头中的 Authorization.
String header = request.getHeader("Authorization");
// 判断是否进行拦截
if (header != null && !"".equals(header) && header.startsWith("Bearer ")) {
// 得到 token
String token = header.substring(7);
// 进行对 token 解析.
try {
Claims claims = jwt.parseJWT(token);
// 得到登录的角色
String role = (String) claims.get("role");
if ("admin".equals(role)) {
request.setAttribute("token_admin", token);
request.setAttribute("claims_admin", claims);
}
if ("user".equals(role)) {
request.setAttribute("token_user", token);
request.setAttribute("claims_user", claims);
}
} catch (Exception e) {
throw new RuntimeException("令牌不正确");
}
}
return true;
}
}
package com.springCloud.user.config.interceptor;
import com.springCloud.user.interceptor.JwtInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
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 {
private JwtInterceptor jwtInterceptor;
/**
* 这里需要是 public 修饰
*
* @param jwtInterceptor jwtInterceptor
*/
@Autowired
public InterceptorConfig(JwtInterceptor jwtInterceptor) {
this.jwtInterceptor = jwtInterceptor;
}
/**
* Registered Interceptor
*
* @param registry registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器要声明拦截器对象和拦截器请求.
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/**/login**/**");
}
}
4. 配置
加上下面的文件防止警告
{
"properties": [
{
"name": "jwt.config.key",
"type": "java.lang.String",
"description": "Description for jwt.config.key.",
"defaultValue": "springCloud"
},
{
"name": "jwt.config.expiration",
"type": "java.lang.Long",
"description": "Description for jwt.config.expiration.",
"defaultValue": 3600000
}
]
}
在配置文件中
jwt:
config:
expiration: 3600000
key: key
5. 使用
添加
private UserService userService;
private RedisTemplate<String, String> redisTemplate;
private HttpServletRequest request;
private JWT jwt;
/**
* 获取容器对象
*
* @param userService 识别 userService 容器对象
*/
@Autowired
private UserController(UserService userService,
RedisTemplate<String, String> redisTemplate,
HttpServletRequest request,
JWT jwt) {
this.userService = userService;
this.redisTemplate = redisTemplate;
this.request = request;
this.jwt = jwt;
}
/**
* 登录用户时需要前后端通话的操作 JWT
*
* @param user 用户
* @return Result
*/
private Result login_jwt(User user) {
String token = this.jwt.createJWT(user.getId(), user.getName(), "user");
Map<String, Object> map = new HashMap<>();
map.put("id", user.getId());
map.put("role", "user");
map.put("token", token);
return new Result(StatusCode.OK, true, "用户登录成功", map);
}
/**
* 手机号登录
*
* @param user 用户
* @return Result
*/
@PostMapping("/login_phone")
public Result login_phone(@RequestBody User user) {
User login = userService.login_phone(user);
if (login == null) {
return new Result(StatusCode.LOGIN_ERROR, false, "用户登录失败");
}
// 登录成功了, 需要进行前后端通话的操作. JWT
return login_jwt(login);
}
/**
* 自动登录
*
* @return Result
*/
@PostMapping("/authLogin")
public Result login() {
Claims token_user = (Claims) request.getAttribute("claims_user");
String id = token_user.getId();
String role = (String) token_user.get("role");
if (role == null || "".equals(role)) {
return new Result(StatusCode.LOGIN_ERROR, false, "登录失效");
}
// 登录成功了, 需要进行前后端通话的操作. JWT
return new Result(StatusCode.OK, true, "自动登录成功", userService.findById(id));
}