环境搭建
1.导入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.0</version>
</dependency>
2.JWTUtil
public class JWTUtil {
private static String TOKEN = "xie_hao";
/**
* 生成token
*
* @param map
* @return
*/
public static String getToken(Map<String, String> map) {
JWTCreator.Builder builder = JWT.create();
map.forEach((k, v) -> {
builder.withClaim(k, v);
});
Calendar instance = Calendar.getInstance();
instance.add(Calendar.MINUTE, 10);
builder.withExpiresAt(instance.getTime());
return builder.sign(Algorithm.HMAC256(TOKEN)).toString();
}
/**
* 获取token中的payload
*
* @param token
* @return
*/
public static DecodedJWT verify(String token) {
return JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);
}
}
2.JWTInterceptors
public class JWTInterceptors implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Map<String, Object> map = new HashMap<>();
// 获取请求头中的令牌
String token = request.getHeader("token");
try {
JWTUtil.verify(token);// 验证令牌
return true;//直接放行
} catch (SignatureVerificationException e) {
e.printStackTrace();
map.put("msg", "无效签名");
} catch (TokenExpiredException e) {
e.printStackTrace();
map.put("msg", "令牌过期");
} catch (AlgorithmMismatchException e) {
e.printStackTrace();
map.put("msg", "把算法不一致");
} catch (Exception e) {
e.printStackTrace();
map.put("msg", "令牌无效");
}
map.put("state", false);
// map响应到前端
String json = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
4.InterceptorsConfig
@Configuration
public class InterceptorsConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptors())
.addPathPatterns("/hao/**")// 需要拦截的接口 /** 全部接口
.excludePathPatterns("/hao/userInfo/login"); // 可以放行的接口
}
}
实现login()
service层
public UserInfo login(UserInfo user) {
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper
.eq("username", user.getUsername())
.eq("password", user.getPassword());
UserInfo userInfo = mapper.selectOne(queryWrapper);
if(userInfo!=null){
return userInfo;
}
throw new RuntimeException("登录失败");
}
controller层
@Controller
@RequestMapping("/hao/userInfo")
public class UserInfoController {
@Resource
private UserInfoService service;
@GetMapping("/getuser")
@ResponseBody
public Object getuser(@RequestParam("id") Integer id) {
return service.findUserById(id);
}
@GetMapping("/login")
@ResponseBody
public Map<String, Object> login(@RequestParam("name") String name, @RequestParam("password") String password) {
Map<String, Object> map = new HashMap<String, Object>();
UserInfo user = new UserInfo();
user.setUsername(name);
user.setPassword(password);
try {
UserInfo userLogin = service.login(user);
Map<String, String> payload = new HashMap<>();
payload.put("id", userLogin.getId().toString());
payload.put("name", userLogin.getUsername());
payload.put("password", userLogin.getPassword());
// 生成JWT令牌
String token = JWTUtil.getToken(payload);
map.put("state", true);
map.put("msg", "登录成功");
map.put("token", token);
} catch (Exception e) {
map.put("state", false);
map.put("msg", e.getMessage());
}
return map;
}
}
接口测试
断言:
/hao/userInfo//login请求不需要携带token进行拦截校验,由服务器返回token
/hao/userInfo//getuser请求需要携带登录时服务器返回的token进行拦截校验,否则无法获得数据
测试:
http://localhost:8080/hao/userInfo/login?name=hao&password=123获得token返回,可以利用该token进行访问getuser接口。
上图为访问getuser接口但不在请求头中携带token的返回结果
在请求头中携带第一次登录时服务器返回的token,发现此时可以通过jwt安全验证,获得数据。