背景介紹
在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);
}