JWT
最近看网课学的一点内容,存下的笔记,仅供参考
1.定义
2.核心作用:1.信息交换
2.javaweb中的安全授权验证
3.传统session认证
4.基于JWT认证
认证通过之后生成的JWT(令牌)会本地保存(浏览器端),和服务端没有关系,当日后验证的时候会携带生成并保存的JWT,由拦截器进行验证,检查
4.1 jwt认证流程
4.2 优势
5. JWT的结构
注意:payload中放的是用户的信息及其他数据的声明,当请求时,服务端会对payload进行Base64进行编码加密,返回之后可以被翻译回来。所以,payload中不能存放敏感信息(密码)。
三者组合到一起
6.JWT的使用
6.1.引入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
6.2.生成token
@Test
void jwtTest() {
HashMap<String ,Object > map = new HashMap<>();
//设置令牌的过期时间
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND,100000);
//声明
String token = JWT.create()
.withHeader(map) //header(可不用写)
.withClaim("userId",12) //payload
.withClaim("username","sadiashd")
.withExpiresAt(instance.getTime()) //指定令牌的过期时间
.sign(Algorithm.HMAC256("#@$##%*^$%")); //签名
System.out.println(token);
}
6.3.根据令牌和签名解析数据
@Test
public void test1() {
//创建验证对象
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("#@$##%*^$%")).build();
DecodedJWT decodedJWT = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NTkwMjUzMDIsInVzZXJJZCI6IjExIiwidXNlcm5hbWUiOiJzYWRpYXNoZCJ9.6to07WNNSZ8upTMjCbI4bbbY10g2FLYbAyn0UkPp1Rg\n");
System.out.println(decodedJWT.getClaim("userId").asString());
System.out.println(decodedJWT.getClaim("username").asString());
}
6.4.常见的异常信息
6.5.JWT工具类的封装
public class JWTUtils {
//鉴权 相当于私钥保存在服务器上(只能自己知道)
private static final String secret="##@$%@#S#WS";
public static String getToken(Map<String,String> map)
{
Calendar instance=Calendar.getInstance();
//默认七天过期
instance.add(Calendar.DATE,7);
//创建JWT
JWTCreator.Builder builder = JWT.create();
//map集合 动态的传数据
//payload
map.forEach((k,v)->{
builder.withClaim(k,v);
});
//指定令牌过期时间
builder.withExpiresAt(instance.getTime());
String token=builder.sign(Algorithm.HMAC256(secret));
return token;
}
/**
* 验证token 合法性
*/
public static DecodedJWT verify(String token) {
return JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
}
/**
* 获取token信息的方法
*/
public static DecodedJWT getTokenInfo(String token){
DecodedJWT verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
return verify;
}
}
7.JWT的使用
@Data
public class User {
private Integer id;
private String username;
private String password;
}
@Mapper
public interface UserDao {
@Select("select * from ssm.user where username=#{username} and password=#{password} ")
public User login(User user);
}
public interface UserService {
public User login(User user);
}
@Service
@Transactional
public class USerServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public User login(User user) {
//根据用户名和密码查询数据库
User userDb = userDao.login(user);
if (userDb != null){
return userDb;
}
throw new RuntimeException("登录失败");
}
}
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/login")
public Map<String ,Object> login(User user){
log.info("用户名::[{}]",user.getUsername());
log.info("密码:[{}]",user.getPassword());
Map<String ,Object> map = new HashMap<>();
try {
User userDb = userService.login(user);
//将用户信息存在集合中
Map<String ,String> payload = new HashMap<>();
payload.put("用户id:", String.valueOf(userDb.getId()));
payload.put("用户名:",userDb.getUsername());
//生成token
String token = JWTUtils.getToken(payload);
map.put("state:", true);
map.put("msg", "认证成功");
//响应token
map.put("token",token);
}catch (Exception e ){
map.put("state",false);
map.put("msg",e.getMessage());
}
return map;
}
// @PostMapping("/test")
// public Map<String ,Object> test(String token){
// Map<String ,Object> map = new HashMap<>();
// //打印当前token信息
// log.info("token:[{}]",token);
// try{
// //验证token
// DecodedJWT verify = JWTUtils.verify(token);
// map.put("stage:",true);
// map.put("msg:","请求成功");
// return map;
// }catch (StringIndexOutOfBoundsException e){
// e.printStackTrace();
// map.put("msg:","无效签名");
// }catch (TokenExpiredException e){
// e.printStackTrace();
// map.put("msg:","token过期");
//
// }catch (AlgorithmMismatchException e){
// e.printStackTrace();
// map.put("msg:","无效签名");
//
// }catch (Exception e){
// e.printStackTrace();
// map.put("msg","token无效");
// }
// map.put("state",false);
// return map;
// }
@PostMapping("/test")
public Map<String ,Object> test(HttpServletRequest request){
Map<String ,Object> map = new HashMap<>();
//处理自己的业务逻辑
// //获取token
// String token = request.getHeader("token");
// DecodedJWT verify = JWTUtils.verify(token);
// log.info("用户id:[{}]",verify.getClaim("id").asString());
// log.info("用户名name:[{}]",verify.getClaim("username").asString());
map.put("stage:",true);
map.put("msg:","请求成功");
return map;
}
}
public class JWTInterceptor 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{
//验证token
JWTUtils.verify(token);
return true;//放行
}catch (StringIndexOutOfBoundsException e){
e.printStackTrace();
map.put("msg:","无效签名");
}catch (TokenExpiredException e){
e.printStackTrace();
map.put("msg:","token过期");
}catch (AlgorithmMismatchException e){
e.printStackTrace();
map.put("msg:","无效签名");
}catch (Exception e){
e.printStackTrace();
map.put("msg","token无效");
}
map.put("state",false);//设置状态
//将map转换为json格式
String string = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().print(string);
return false;
}
}
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("user/test") //其他接口需要进行拦截,进行token验证
.excludePathPatterns("user/user");//所以用户接口都放行
}
}