Spring Boot 如何从 React JS 获取当前用户?

How does SpringBoot get current user from ReactJS?

我试图在 https://github.com/callicoder/spring-security-react-ant-design-polls-app 了解全栈网络应用程序的代码 但我不明白 spring-boot 如何知道当前登录的是哪个用户。

这是调用 api 的 ReactJS(前端)代码。

export function getUserCreatedPolls(username, page, size) {
    page = page || 0;
    size = size || POLL_LIST_SIZE;

    return request({
        url: API_BASE_URL + "/users/" + username + "/polls?page=" + page + "&size=" + size,
        method: 'GET'
    });
}

而且,这是spring-boot(后端)代码,从前端接收变量

@GetMapping("/users/{username}/polls")
public PagedResponse<PollResponse> getPollsCreatedBy(@PathVariable(value = "username") String username,
                                                     @CurrentUser UserPrincipal currentUser,
                                                     @RequestParam(value = "page", defaultValue = AppConstants.DEFAULT_PAGE_NUMBER) int page,
                                                     @RequestParam(value = "size", defaultValue = AppConstants.DEFAULT_PAGE_SIZE) int size) {
    return pollService.getPollsCreatedBy(username, currentUser, page, size);
}
  1. spring-boot如何从前端获取{UserPrincipal currentUser}?
  2. ReactJs如何将{UserPrincipal currentUser}发送到后端?
  • 这是一个 spring 引导 oauth jwt 提供者 + 资源服务器 和 ReactJs 作为 消费者

  • ReactJs 可以通过发送和 HTTP 请求 来消耗服务器资源(rest api),但它应该首先获得授权(令牌)
  • 服务器会在登录成功后发送JWT token
  • 然后当 reacteJs 发送 HTTP 请求时,它实际上向 HTTP 请求注入了额外的信息,即 授权令牌
  • 当服务器得到这个请求并且在它到达控制器之前,请求传递抛出一个链filter ( spring security filter chain ) , 看看代码中的这个 filter class 方法 link , 成功用户认证后 调用 SecurityContextHolder class 以 使用 当前经过身份验证的用户 填充安全上下文 ( User Principle ),最后当request 到达controller,我们的security context填满
  • @CurrentUser UserPrincipal currentUser ,当您将 UserPrincipal currentUser 参数添加到 spring Controller 方法时,它将自动从上下文中填充对象,您可以通过调用 SecurityContextHolder class 并获取当前的 authenticated User

     ...
    
     // Get The Jwt token from the HTTP Request
     String jwt = getJwtFromRequest(request);
     // Check The validation of JWT - if true the user is trusted
     if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
      Long userId = tokenProvider.getUserIdFromJWT(jwt);
    
      /*
          Note that you could also encode the user's username and roles inside JWT claims
          and create the UserDetails object by parsing those claims from the JWT.
          That would avoid the following database hit. It's completely up to you.
       */
      // Get the user object
      UserDetails userDetails = customUserDetailsService.loadUserById(userId);
      UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
      authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
      // Fill the security context with this user 
      SecurityContextHolder.getContext().setAuthentication(authentication);
    
     ...