상황 : OAuth2 로그인을 진행하는 사용자에 대해 서버는 인증 서버에서 발급 받은 토큰과 같은 정보를 메모리에 저장하며 관리한다. 이 때 소셜 로그인 사용자 수가 늘고, 서버의 스케일 아웃을 진행할 시에 문제가 발생할 수 있다.

 

해결책 : 토큰과 같은 정보를 메모리에 저장하는 방식이 아닌, DB에 저장하는 방식으로 OAuth2AuthorizedClientService를 커스텀해야 한다.

 

OAuth2AuthorizedClientService

@Configuration
public class CustomOauth2AuthorizedClientService {

    @Bean
    public OAuth2AuthorizedClientService authorizedClientService(JdbcTemplate jdbcTemplate, ClientRegistrationRepository clientRegistrationRepository) {
        return new JdbcOAuth2AuthorizedClientService(jdbcTemplate, clientRegistrationRepository);
    }
}

 

SecurityConfig

private final OAuth2AuthorizedClientService authorizedClientService;

...

http
	.oauth2Login(oauth2 -> oauth2
		.authorizedClientService(authorizedClientService));

 

이 때 주의할 점으로는 아래의 테이블을 db에 미리 저장해놔야 한다.

CREATE TABLE oauth2_authorized_client (
  client_registration_id varchar(100) NOT NULL,
  principal_name varchar(200) NOT NULL,
  access_token_type varchar(100) NOT NULL,
  access_token_value blob NOT NULL,
  access_token_issued_at timestamp NOT NULL,
  access_token_expires_at timestamp NOT NULL,
  access_token_scopes varchar(1000) DEFAULT NULL,
  refresh_token_value blob DEFAULT NULL,
  refresh_token_issued_at timestamp DEFAULT NULL,
  created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
  PRIMARY KEY (client_registration_id, principal_name)
);

기본키를 보면 client_registration_id와 principal_name인 걸 볼 수 있다. 이 때 client_registration_id는 kakao와 같은 서비스명이고, principal_name은 OAuth2User에서 getName() 함수에서 반환된 값이다. 따라서 이는 충분히 중복될 가능성이 있으므로 이에 대해 커스텀을 진행해야 한다.

 

+ Recent posts