-
OAuth2.0과 JWT적용 - 3스프링 2023. 1. 25. 22:17
처음 들어오는 사용자가 OAuth로그인 후 -> 처음 들어오는 사용자면 DB에 정보 저장후 -> 토큰 발급
이러한 로직을 수행하려고 한다.
우선 Controller를 먼저 구성해보자
@RestController @RequiredArgsConstructor public class MemberController { private final OAuthService oAuthService; @GetMapping("/oauth/login") public ResponseEntity<Token> loginController(@AuthenticationPrincipal OAuth2User oAuth2User) { return ResponseEntity.ok(oAuthService.login(oAuth2User.getAttributes())); } }
return되는 저것은 우선 신경쓰지 말자.
전에 구성했던 OAuthUserService를이용해 loadUser로 대항 OAuth인증을 하는 사용자 정보를 가지고 온다.
(https://winwin-k9.tistory.com/106 이전글은 여기 참고)
스프링 시큐리티는 SecurityContext에 인증된 Authentication 객체를 넣어두고 현재 스레드 내에서 공유되도록 관리한다.
OAuthService
@Service @RequiredArgsConstructor public class OAuthService { private final MemberRepository memberRepository; private final TokenService tokenService; @Transactional public Token login(Map<String, Object> attribute) { String email = (String) attribute.get("email"); String name = (String) attribute.get("name"); if (memberRepository.findByEmail(email) == null) { Member member = new Member(email, name); memberRepository.save(member); } return tokenService.generateToken(email, name); } }
OAuth인증 사용자로 부터 Attribute를 가져온다. 인증된 사용자의 Attribute는 속성으로 Map구조로 되어있다.
이 정보를 받아서 해당 유저가 DB에 이미 저장이 되어있지 않으면 정보를 저장(회원가입 처리)후
토큰을 발급해주도록 한다.
다음은 Security설정이다.
@Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig { private final OAuthUserService oAuthUserService; private final JwtFilter jwtFilter; @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors() .and() .csrf().disable() .authorizeHttpRequests().anyRequest().permitAll() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER) //세션사용 안함 .and() .formLogin() .and() .oauth2Login() //OAuthLogin 설정 .userInfoEndpoint() // oauth2Login 설정을 시작 .userService(oAuthUserService) // 로그인을 oAuthUserService에서 처리 .and() .defaultSuccessUrl("/oauth/login"); http.addFilter(jwtFilter); return http.build(); } }
OAuth로그인이 끝나면 url이 defaultSuccessUrl인 /oauth/login 으로 이동하게 된다.
여기서 오류가 발생하는데
does not have a registered order and cannot be added without a specified order
addFilter는 메서드를 사용하기 위해서는 반드시 Spring Security Framework 에서 제공되는 필터 혹은 이를 확장한 객체이어야 한다.
따라서 addFilterBefore나 After를 사용해야 한다.
따라서 다음과 같이 변경해야 한다.
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
UsernamePasswordAuthenticationFilter는 Form인증을 처리하는 필터이다.
사용자가 로그인하면 인증처리가 이루어지는데, 이 인증처리를 담당하고 관련된 요청을 처리한다.
http://localhost:8080/oauth2/authorization/google
OAuth인증을 하는 해당 URL로 접속후, 로그인을 하면
아래와 같이 토큰을 발급받는것을 확인할 수 있다.
728x90'스프링' 카테고리의 다른 글
API 예외처리-2 (0) 2023.01.27 API 예외처리-1 (0) 2023.01.26 UsernamePasswordAuthenticationFilter (0) 2023.01.19 JWT 토큰 체크 (0) 2023.01.19 OAuth2.0과 JWT적용 - 2 (0) 2023.01.17