POM中引入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.2</version>
</dependency>
新建工具类JwtUtil.java
package sgcc.project.mall.common.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sgcc.project.mall.entity.User;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Jwt工具类进行token的生成和认证
*/
public class JwtUtil {
private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);
/**
* 密钥
*/
private static final String SECRET = "my_secret";
/**
* 过期时间
**/
private static final long EXPIRATION = 1800L;//单位为秒
/**
* 生成用户token,设置token超时时间
*/
public static String createToken(User user) {
//过期时间
Date expireDate = new Date(System.currentTimeMillis() + EXPIRATION * 1000);
Map<String, Object> map = new HashMap<>();
map.put("alg", "HS256");
map.put("typ", "JWT");
String token = JWT.create()
.withHeader(map)// 添加头部
//可以将基本信息放到claims中
.withClaim("id", user.getId())//userId
.withClaim("userName", user.getUserName())//userName
.withClaim("name", user.getName())//name
.withExpiresAt(expireDate) //超时设置,设置过期的日期
.withIssuedAt(new Date()) //签发时间
.sign(Algorithm.HMAC256(SECRET)); //SECRET加密
return token;
}
/**
* 校验token并解析token
*/
public static Map<String, Claim> verifyToken(String token) {
DecodedJWT jwt = null;
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
jwt = verifier.verify(token);
} catch (Exception e) {
logger.error(e.getMessage());
logger.error("token解码异常");
return null;
}
return jwt.getClaims();
}
}
新建用户对象User.java
package sgcc.project.mall.entity;
import lombok.Data;
@Data
public class User {
private Integer id;// 序号
private String name;// 姓名拼音
private String userName;// 真实姓名
private String password;// 密码
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
用户接口,创建Token
package sgcc.project.mall.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import sgcc.project.mall.common.jwt.JwtUtil;
import sgcc.project.mall.controller.base.BaseController;
import sgcc.project.mall.controller.base.BaseEnum;
import sgcc.project.mall.controller.base.BaseResponse;
import sgcc.project.mall.entity.User;
@RestController
@RequestMapping("/login")
@Slf4j
public class LoginController extends BaseController {
/**
* 模拟用户 登录
* @return
*/
@RequestMapping("/go")
@ResponseBody
public BaseResponse<String> login(@RequestBody User requestUser) {
if ("zhangsan".equals(requestUser.getName()) && "123456".equals(requestUser.getPassword())) {
User user = new User();
user.setId(1);
user.setName(requestUser.getName());
user.setPassword(requestUser.getPassword());
user.setUserName("张三");
String token = JwtUtil.createToken(user);
return success(token);
}
return tokenError();
}
}
过滤器验证Token
package sgcc.project.mall.common.jwt;
import com.auth0.jwt.interfaces.Claim;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
@WebFilter(filterName = "JwtFilter", urlPatterns = "/tTree/*")
public class JwtFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
response.setCharacterEncoding("UTF-8");
//获取header里的token
final String token = request.getHeader("authorization");
// OPTIONS请求相当于一个检测目标是否安全的操作,
// 类似于心跳机制。所以我们在后台拦截器里面应该把这个请求过滤掉。
// 如果检测到请求方法是options,则直接通过,接下来会得到真正的请求。
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
chain.doFilter(request, response);
}
// 除选项外,其他请求应由JWT检查
else {
if (token == null) {
response.getWriter().write("没有token!");
return;
}
Map<String, Claim> userData = JwtUtil.verifyToken(token);
if (userData == null) {
response.getWriter().write("token不合法!");
return;
}
Integer id = userData.get("id").asInt();
String name = userData.get("name").asString();
String userName = userData.get("userName").asString();
//拦截器 拿到用户信息,放到request中
request.setAttribute("id", id);
request.setAttribute("name", name);
request.setAttribute("userName", userName);
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
}
}