为了解决用户登录认证的问题,引入了jwt令牌
1.jwt令牌的生成
1.引入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.3.0</version>
</dependency>
2.调用API并且进行解析
2.jwt工具类的代码
public class JwtUtil {
private static final String KEY = "itheima";
//接收业务数据,生成token并返回
public static String genToken(Map<String, Object> claims) {
return JWT.create()
.withClaim("claims", claims)
//过期时间设置为12小时
.withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 12))
//加密方式的选择
.sign(Algorithm.HMAC256(KEY));
}
//接收token,验证token,并返回业务数据
public static Map<String, Object> parseToken(String token) {
return JWT.require(Algorithm.HMAC256(KEY))
.build()
.verify(token)
.getClaim("claims")
.asMap();
}
}
3.将代码加入登录的代码中,登录时生成了jwt令牌
if (Md5Util.getMD5String(password).equals(loginUser.getPassword())){
//生成一个jwt的令牌,生成token返回给用户
HashMap<String, Object> claims = new HashMap<>();
claims.put("id",loginUser.getUsername());
claims.put("username",loginUser.getPassword());
String token = JwtUtil.genToken(claims);
//登录成功
return Result.success(token);
}
返回的结果如下图所示
4.验证token,实现一个拦截器
拦截器的代码
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//令牌验证
String token = request.getHeader("Authorization");
//验证token是否合法
try {
Map<String, Object> claims = JwtUtil.parseToken(token);
//放行
return true;
} catch (Exception e) {
response.setStatus(401);
//设置为401,不放行
return false;
}
}
}
5.对拦截器进行注册
//配置类的注解
@Configuration
//注册一个拦截器
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//登录注册接口不拦截,进行放行
registry.addInterceptor(loginInterceptor)
.excludePathPatterns("/user/login","/user/register");
}
}
登录后返回的状态码是200
未登录是401
##6. 获取用户的详细信息
mybatis:
configuration:
map-underscore-to-camel-case: true #开启驼峰命名和下划线命名自动转换
代码如下
//查询用户
@GetMapping("/userInfo")
public Result<User> userInfo(@RequestHeader(name="Authorization") String token)
{
//根据用户名查询用户
Map<String, Object> map = JwtUtil.parseToken(token);
String username = (String) map.get("username");
User user = userService.findByUserName(username);
return Result.success(user);
}
查询结果如下
7.使用ThreadLocal来优化代码
查询用户代码优化后如下
//查询用户
@GetMapping("/userInfo")
public Result<User> userInfo()
{
//根据用户名查询用户
// Map<String, Object> map = JwtUtil.parseToken(token);
// String username = (String) map.get("username");
Map<String , Object> map = ThreadLocalUtil.get();
String username = (String) map.get("username");
User user = userService.findByUserName(username);
return Result.success(user);
}
8.用户更新
基本代码如下
@PutMapping("/update")
public Result update(@RequestBody User user){
userService.updateUser(user);
//
return Result.success();
}
@Override
public void updateUser(User user) {
user.setUpdateTime(LocalDateTime.now());
userMapper.updateUser(user);
}
@Update("update user set nickname=#{nickname},email=#{email},update_time=#{updateTime} where id=#{id}")
void updateUser(User user);
要对参数进行校验,所以要对代码进行修改
如何对实体参数进行校验???
- 首先在实体类添加如下的注解
- 在接口方法参数中添加注解,表明校验生效