首页 > 解决方案 > SpringBoot 如何从 ReactJS 获取当前用户?

问题描述

我试图在https://github.com/callicoder/spring-security-react-ant-design-polls-app了解全栈 Web 应用程序的代码, 但我不明白 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(back-end) 代码

@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} 发送到后端?

标签: springreactjsspring-bootlogin-control

解决方案


  • 这是一个 Spring Boot oauth jwt 提供者 + 资源服务器和 ReactJs 作为消费者

在此处输入图像描述

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

     ...
    
     // 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);
    
     ...
    

推荐阅读