Mingyum-Kim / Iamhere

😉 국내 거주 외국인 매칭 서비스 "I-am-here" 😉
1 stars 0 forks source link

로그인한 사용자 정보 불러오기 #29

Closed Mingyum-Kim closed 1 year ago

Mingyum-Kim commented 1 year ago

Jwt를 이용해서 로그인한 경우 로그인한 사용자 정보를 불러오는 방법을 알아보자.

  1. Access Token을 이용한 방법

@AuthenticationPrincipal 를 Controller 단에 있는 메소드의 파라미터로 사용해서 UserDetailService에서 반환한 객체를 파라미터로 사용할 수 있다. 이제 Service 단에서 User 객체를 통해 사용자의 로그인 아이디를 가져와 멤버 객체를 찾을 수 있다. 여기서 user.getUsername의 반환값은 로그인 유저의 고유 식별자로 예상된다. 따라서 memberRepositoryfindById 메소드를 호출하여 멤버 객체를 찾아본다.

원리 : JWT 인증이 완료된 사용자의 정보는 SecurityContextAuthentication 객체의 Principal 필드에 정의되어있다.

참고 자료 : https://sas-study.tistory.com/410

Mingyum-Kim commented 1 year ago

JwtUtil에서 JWT 토큰을 생성할 때 아래와 같이 Claims에 mail 값을 넣었다.

  public static String createToken(String mail, String key, long expireTimeMs) {
        Claims claims = Jwts.claims();
        claims.put("mail", mail);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expireTimeMs))
                .signWith(SignatureAlgorithm.HS256, key)
                .compact();
    }

실제로 memberService에서 이 함수를 호출할 때도 사용자의 메일을 넣었다.

 if (bCryptPasswordEncoder.matches(loginDTO.getPassword(), member.getPassword())) {
            String token = JwtTokenUtil.createToken(member.getMail(), key, expireTimeMs);
            return token;
        }

그렇다면 @AuthenticatoinPrincipal을 이용해서 사용자의 이메일을 추출할 수 있지 않을까?

Mingyum-Kim commented 1 year ago

결론적으로 Authentication authentication을 컨트롤러 메서드의 파라미터로 넣어서, authentication.getName()을 통해 사용자의 메일을 추출해주었다.

추가 : SecurityConfig에서 permitAll() 로 지정된 API여도 여전히 JwtFilter을 거치는 것 같다. 그러나, 그동안 JWTfilter에서 설정한 대로 JWT 토큰의 유효성 검사가 진행되지 않은 이유는 아래 코드를 추가하지 않아서이다.

                        .anyRequest().authenticated()

permitAll()과 별개로 JWT 인증을 거치고 싶은 URL에 대해서는 authenticated() 설정을 해주어야 한다.