How does SpringBoot get current user from ReactJS?

1.5k Views Asked by At

I trying to understand the codes of Full-stack web-application at https://github.com/callicoder/spring-security-react-ant-design-polls-app but I do not understand how does spring-boot know which current user is logging in.

this is ReactJS (front-end) code that calls the api.

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'
    });
}

And, this is spring-boot(back-end) code that receives variables from front-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. how does spring-boot get {UserPrincipal currentUser} from front-end?
  2. how does ReactJs sent {UserPrincipal currentUser} to back-end?
1

There are 1 best solutions below

0
Djamel Korei On BEST ANSWER
  • It's a spring boot oauth jwt provider + resource server and ReactJs as the consumer

enter image description here

  • ReactJs can consume the server resources ( rest api ) by sending and HTTP request, but it should first get an authorization for that (Token)
  • The server will send JWT token after a success login
  • then when reacteJs send an HTTP request, it actually inject extra information to the HTTP request which is the authorization token
  • when the server get this request and before it reach the controller, the request pass throw a chain of filter ( spring security filter chain ) , look at this filter class method in the code link , after a success user authentication calling the SecurityContextHolder class to fill the security context with the current authenticated user ( User Principle ), and finally when the request reach the controller, our security context is filled up
  • @CurrentUser UserPrincipal currentUser , when you added UserPrincipal currentUser parameter to spring Controller methods, it will fill the object from the context automatically, you can do it by your self by calling the SecurityContextHolder class and get the current 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);
    
     ...