How does the JWT token convert the token token into the login information?

Get into the habit of writing together! This is the first day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

1. The role of HandlerMethodArgumentResolver and its method explanation:

HandlerMethodArgumentResolver is an interface with two methods:

public interface HandlerMethodArgumentResolver {
    boolean supportsParameter(MethodParameter parameter);
    @Nullable
    Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
复制代码

You can probably guess by looking at the method name:

The return value of the supportsParameter method is boolean. Its function is to judge whether the parameters in the Controller layer meet the conditions. If the conditions are met, the resolveArgument method will be executed. If not, skip it.

resolveArgument method, which will only be called if the supportsParameter method returns true. It is used to process some business and assign the return value to this parameter in the Controller layer.

We can understand HandlerMethodArgumentResolver as a parameter resolver. We can modify the method parameters in the Controller layer by writing a class that implements the HandlerMethodArgumentResolver interface.

2. Project realization

1. For example, after logging in with JWT, we need to obtain detailed information such as the information of the current login person and the permission menu through the following interface.

@GetMapping("/routes")
@ApiOperationSupport(order = 7)
@ApiOperation(value = "前端菜单数据", notes = "前端菜单数据")
public R<List<MenuVO>> routes(HttpServletRequest request) {
    Claims claims = getClaims(request);
    if (claims == null) {
        return null;
    } else {
        Long userId = claims.get("user_id");
        String roleId = claims.get("role_id");
        String deptId = claims.get("dept_id");
        String account = claims.get("account");
        String roleName = claims.get("role_name");
        String userName = claims.get("user_name");
        User user = new User();
        user.setUserId(userId);
        user.setTenantId(tenantId);
        user.setAccount(account);
        user.setRoleId(roleId);
        user.setDeptId(deptId);
        user.setRoleName(roleName);
        user.setUserName(userName);
    }
	List<MenuVO> list = menuService.routes((user == null || user.getUserId() == 0L) ? null : user.getRoleId());
	return R.data(list);
}
复制代码

However, in the project, each interface must obtain parameters in this way, so the code is too bloated. We can modify it a little bit and use the HandlerMethodArgumentResolver interface:

2. First write an implementation class to implement the methods in this interface:

public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
    private static final Logger log = LoggerFactory.getLogger(TokenArgumentResolver.class);
    public TokenArgumentResolver() {
    }
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(User.class);
    }
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
        return SecureUtil.getUser();
    }
}
复制代码

Then add this implementation class to the project's interception:

@Configuration(
    proxyBeanMethods = false
)
@EnableCaching
@Order(-2147483648)
public class MyWebMvcConfiguration implements WebMvcConfigurer {
    private static final Logger log = LoggerFactory.getLogger(BladeWebMvcConfiguration.class);
    public MyWebMvcConfiguration() {
    }
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new TokenArgumentResolver());
    }
}
复制代码

In this way, when the project interface is requested, it will enter our custom TokenArgumentResolver class to resolve the interface class and parameter information.

Then, our interface can be written like this:

@GetMapping("/routes")
@ApiOperationSupport(order = 7)
@ApiOperation(value = "前端菜单数据", notes = "前端菜单数据")
public R<List<MenuVO>> routes(User user) {
	List<MenuVO> list = menuService.routes((user == null || user.getUserId() == 0L) ? null : user.getRoleId());
	return R.data(list);
}
复制代码

In this way, each interface does not need to parse the token in the request header, and the user information corresponding to the token can be obtained.

Guess you like

Origin juejin.im/post/7083659489815035918