Spring Security , OAuth2 authorizedClient 데이터베이스에 영속화 하기

유알·2024년 1월 20일
0

AuthorizedClient란 쉽게 말하면, Google, FaceBook으로 받은 accessToken, refreshToken들을 말한다
(엄밀한 의미는 아니다. 이것을 포함한 말그대로 허가된 클라이언트 프로퍼티를 말한다. 직접 객체를 찾아가 보길 바란다)

근데 Spring Boot 기준 기본 구현은 Inmemory로 되어 있다. 즉 서버를 여러개 띄우면 서로 공유가 안된다는 거다.(매번 요청을 하겠죠?)

Spring security에서는 org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository 를 통해서 이를 영속화 하도록 구현이 되어 있다.

위와 같은 기본 구현채들이 있는데, 첫번째꺼는 뒤에서 말할 OAuth2AuthorizedClientService에 delgate 하는 구현체고, 두번째꺼는 세션, 세 번째 꺼는 테스트 용이다.

기본적으로는 첫번째 구현체가 사용되는데, Spring boot를 사용할 경우, 다음과 같이 설정하면 된다.

    @Bean
    public OAuth2AuthorizedClientService authorizedClientService(
            JdbcOperations jdbcOperations,
            ClientRegistrationRepository clientRegistrationRepository // google, facebook, kakao 등의 client 정보를 가지고 있다.
    ) {
        return new JdbcOAuth2AuthorizedClientService(jdbcOperations, clientRegistrationRepository);
    }

OAuth2AuthorizedClientService 빈이 감지되면 자동으로 설정해준다.
인자로 받는 ClientRegistrationRepository의 경우, 우리가 흔히 생각하는 Oidc 제공자, google, naver 이런 회사의 정보를 로드하는 인터페이스다. 기본적으로 인메모리로 구현이 되어 있는데, 만약 property로 설정한다면 로드해준다.(나는 구지 바꿀 필요가 없어서 그냥 쓴다.)

중요한 것은 이 Jdbc 구현체를 쓸때는 당연히 db쪽에 테이블이 있어야한다.

Spring security에서는 다음과 같은 ddl을 제공해준다.

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

나는 postgresql 을 사용하므로, 그거에 맞게 살짝 바꿨다.

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 bytea 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 bytea DEFAULT NULL,
    refresh_token_issued_at timestamp DEFAULT NULL,
    created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
    PRIMARY KEY (client_registration_id, principal_name)
);

이렇게 등록하면, 이제 AuthorizedClient 정보가 db에 영속화 된다

profile
더 좋은 구조를 고민하는 개발자 입니다

0개의 댓글