背景介绍
在web应用中,获取当前访问用户是大多数接口所要处理的事情。如何优雅的获取当前用户信息,是许多人的兴趣。
根据我的经历,认为通过注解来获取当前用户,是一个很好的方式,简便快捷,封装性高。
开始实现
背景就介绍到这里,直接上代码:
UserInfo
用户实体
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {
private String name;
private String avatar;
private String introduction;
private List<String> roles;
}
CurrentUser
用于方法中的参数注解
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
UserArgumentResolver
负责往注解塞数据的解析器,该类的作用是从Request
中获取用户Token
,通过对Token
的处理获取用户id
,再从数据库中拉取用户信息,装载到userInfo.java
。
这里用到了Token
颁发验证框架jjwt
。
@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private JwtOperator jwtOperator;
@Autowired
private UserService userService;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(CurrentUser.class);
}
@Override
public UserInfo resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
String token = request.getHeader("X-Token");
Boolean validateToken = jwtOperator.validateToken(token);
if (!validateToken) {
throw new AuthenticationException("token 不合法或已过期,请重新登录");
}
Claims claimsFromToken = jwtOperator.getClaimsFromToken(token);
Integer userId = (Integer) claimsFromToken.get("userId");
UserInfo userInfo = userService.getUserInfoByUserId(userId.longValue());
return userInfo;
}
}
这里还有一部,就是将我们写的UserArgumentResolver
添加到WebMvcConfig
@Component
public class WebConfig implements WebMvcConfigurer {
@Autowired
private UserArgumentResolver userArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userArgumentResolver);
}
}
验证代码
@GetMapping("/info")
@CheckLogin
public CommonResponse<UserInfo> getUserInfo(@CurrentUser UserInfo userInfo) {
return CommonResponse.ok(userInfo);
}