编写一个小demo实现用户登录生成token,然后在请求header中携带token完成访问用户列表信息。
1.前期工作
1.1新建一张用户表
1.2实体类
@Setter
@Getter
@Entity
@Table(name = "user")
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"})
@DynamicInsert
@DynamicUpdate
public class User {
private static final long serialVersionUID = 1L;
/**
*
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 角色id
*/
private Integer roleId;
}
1.3创建DAO层、service、controller层对应代码
2.jwt登录实现
2.1导入jwt所需依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
2.2新建JwtUtils工具类
public class JwtUtils {
private static final long EXPIRE_TIME = 15 * 60 * 1000;
private static final String TOKEN_SECRET = "mywords"; //密钥盐
/**
* 签名生成
*
* @param user
* @return
*/
public static String sign(User user) {
String token = null;
try {
Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
token = JWT.create().withIssuer("auth0")
.withClaim("username", user.getUsername())
.withExpiresAt(expiresAt)
//使用HMAC256加密
.sign(Algorithm.HMAC256(TOKEN_SECRET));
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
/**
* 签名验证
*
* @param token
* @return
*/
public static boolean verify(String token) {
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
DecodedJWT jwt = verifier.verify(token);
System.out.println(jwt.getIssuer() + "用户名:" + jwt.getClaim("username").asString() + "认证通过");
System.out.println("过期时间:" + jwt.getExpiresAt());
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
2.3添加拦截器
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{
if(request.getMethod().equals("OPTIONS")){
response.setStatus(HttpServletResponse.SC_OK);
return true;
}
response.setCharacterEncoding("utf-8");
String token = request.getHeader("Authorization");
if(token != null){
boolean result = JwtUtils.verify(token);
if(result){
return true;
}
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try{
JSONObject json = new JSONObject();
json.put("success","false");
json.put("msg","认证失败,未通过拦截器");
json.put("code","50000");
response.getWriter().append(json.toJSONString());
System.out.println("认证失败,未通过拦截器");
// response.getWriter().write("50000");
}catch (Exception e){
e.printStackTrace();
response.sendError(500);
return false;
}
return false;
}
}
2.4配置拦截器
@Configuration
public class IntercepterConfig implements WebMvcConfigurer {
private TokenInterceptor tokenInterceptor;
//构造方法
public IntercepterConfig(TokenInterceptor tokenInterceptor){
this.tokenInterceptor = tokenInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry){
List<String> excludePath = new ArrayList<>();
excludePath.add("/register"); //注册
excludePath.add("/login"); //登录
excludePath.add("/logout"); //登出
excludePath.add("/static/**"); //静态资源
excludePath.add("/assets/**"); //静态资源
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludePath);
WebMvcConfigurer.super.addInterceptors(registry);
}
}
2.5controller层实现登录方法
@PostMapping(value = "/login")
public ResultDTO login(@RequestBody @Valid User user){
if(userService.login(user)){
String token = JwtUtils.sign(user);
if(token != null){
return ResultDTO.createSuccess(token);
}else {
return ResultDTO.createFail("token无效!");
}
}else {
return ResultDTO.createFail("用户名或密码错误!");
}
}
service层实现:
/**
* 用户登录查询
*
* @param user
* @return
*/
@Override
public boolean login(User user) {
boolean res = false;
if (!StringUtil.isNullOrEmpty(user.getUsername())) {
User u = userDao.findByUsername(user.getUsername());
if (u != null) {
if(u.getPassword().equals(user.getPassword())){
res = true;
}
}
}
return res;
}
2.6postman测试
登陆成功:
换一个查询详情方法:
失败:
在请求头上添加admin-token便能成功访问