social login + 자체 인증을 동시 지원하는 경우 security 처리는?

2017-06-16 10:36

애플리케이션을 개발하다보면 social login을 지원하면서 서비스 자체적으로 회원을 관리하는 경우가 종종 발생한다. 이와 같이 social login과 자체 인증 기능을 동시에 지원하는 경우의 보안적으로 안전한 방법은 뭘까라는 궁금증에서 출발했다.

인증과 관련해 자체 token 처리, oauth2, jwt 등 상당히 여러 가지 방식이 있는데 이들을 조합해 서비스에 적합한 방법을 찾고 싶었는데 아직까지 명확한 해결책을 찾지 못해 다른 사람들은 어떻게 처리하는지 궁금해서 질문을 남긴다.

모바일과 angular의 백엔드를 지원하는 api 서버에 어떻게 인증을 지원할 것인가로 관련 문서를 찾아봤다.

시작은 Integrating Angular 2 with Spring Boot, JWT, and CORS, Part 1, Integrating Angular 2 with Spring Boot, JWT, and CORS, Part 2 문서에서 시작했다. JWT를 활용해 인증과 인가를 관리하는 방법이다. 이 문서에 포함되어 있는 jwt-spring-security-demo는 자바 웹 백엔드 인증을 시작하는 시작점으로 괜찮았다.

REST Security with JWT using Java and Spring Security 문서도 유용했다.

이 예제 소스는 자체적으로 회원관리를 하는 경우이다. 이 구조에 social login 사용자까지 같이 관리하고 동작하도록 해야 한다. 여기서부터 고민의 시작이다. social login 사용자를 어떻게 관리할 것인가?

클라이언트와의 보안 처리는 JWT를 활용하는 것으로 기준을 세웠다. 그렇다면 social login 사용자와 자체적으로 관리하는 사용자를 JWT를 사용할 수 있도록 통합하는 구조로 설계해 봤다.

관리할 사용자 데이터를 다음과 같이 설계해 봤다.

Account(social login 사용자와 자체 회원 공통 정보)

  • id

MyAccount(자체적으로 관리하는 사용자)

  • userId
  • password
  • name

SocialUser(Social Login 사용자)

  • providerType(페이스북, 구글과 같은 구분자)
  • providerUserId(provider 제공 id)
  • refresh_token

Role(각 계정에 대한 권한)

  • roleId
  • roleName

일단 각 테이블별로 필요한 최소한의 정보만 설계해 봤다. social login의 경우 oauth2를 통해 인증한다고 가정하고 access_token은 굳이 필요없을 것 같아 refresh_token만 저장하는 구조로 잡아봤다.

이와 같이 정보를 저장한 후 사용자가 social login 또는 서비스 자체 로그인을 하는 경우 사용자 정보를 기반으로 JWT를 생성해 클라이언트에 전달하는 방식으로 구조를 잡으면 되지 않을까라고 생각해 봤다.

JWT 토큰에 담을 추가 정보는 사용자 아이디, 이름, expire time, 권한 정보 내용을 포함한다면 stateless 상태로 서비스를 운영할 수 있지 않을까 생각한다.

현장을 떠난지 오래 되어서 그런지 최근 security는 어떻게 처리하는지 궁금하다. 위와 같은 구조로 설계할 경우 보안상 문제가 될 부분이 있을까? 우려되는 부분은 무엇일까? 더 나은 방식으로 설계한다면 어떻게 하면 될까?

참고 문서

0개의 의견 from FB

7개의 의견 from SLiPP

2017-06-16 10:49

요즘 회사에서 프론트엔드 파트라서.. 제가 작성한 코드 경험으로 적어보자면..JWT는 개인프로젝트에서나 조금 적용해봤고, 앱에서의 소셜로그인은 좀 지원해본 적이 있긴한데요.

소셜로그인 정보는 페이스북같은 경우는 액세스토큰, 구글 같은 경우는 아이디토큰과 이메일을 받아서 검증하고.. 해당 토큰 검증이 된 사용자의 경우에는 (USER_CONNECTION 에 사용자 정보가 없다면 회원가입시키고, 있으면 로그인시키는등의) 스프링소셜+웹에서 제공하는 로직을 그대로 태웠던 기억이 나네요.

저같은 경우에는 테이블 구조는 스프링 소셜에서 제공하는 USER_CONNECTION 테이블을 그대로 사용하였습니다. (제가 만들지 않은 코드는 최소한으로 건든다는 주의인지라;;)

아 그런데 앱 로그인같은 경우에는 액세스토큰이라던가 리프레시 토큰을 따로 저장하진 않았었네요.. 스프링소셜에서 userId, providerId, providerUserId 로 로그인처리되지 않나요?(삐질)

2017-06-16 11:00

@아라한사 여기서의 이슈는 social login과 자체 회원을 통합해서 일관되게 관리하고 싶은 것이 요구사항이다. spring social의 경우 USER_CONNECTION 테이블에 access_token, refresh_token이 저장되지 않나? 그런 것으로 알고 있는데..

2017-07-10 16:55

Spring Boot and OAuth2 문서는 Spring Boot와 OAuth2를 활용해 external provider(facebook, github)과의 social login 처리를 하면서 자체적으로 Authorization Server를 구축하는 예제를 포함하고 있다.

이 예제에 더해 자체적으로 회원을 관리하는 기능을 추가한다면 외부 social login도 지원하면서 자체적인 회원관리도 가능한 구조가 되겠다. 이 예제 기반으로 구현할 경우 여러 개의 외부 provider와 자체 회원을 관리하면서 자체적인 Authorization Server 구축이 가능하겠다. 자체적인 Authorization Server 구축이 가능하다면 클라이언트와의 token 교환을 access_token 자체적으로 할 것인지, 아니면 JWT와 같은 전략을 사용하는 것은 또 다른 이슈로 판단된다. 이와 관련한 내용은 JWT 방식으로 바꿔보자 문서 참고해서 JwtTokenStore 사용하면 쉽게 해결할 수 있겠다.

2019-07-26 00:32

혹시 이것에 대한 만족스러웃 답을 찾으셧는지 궁금합니다 위와같은구조는 Js 나 android 같은 클라이언트단에서 프로바이더(예 카카오) 에서 토큰을 받아 자체인증서버로 전달해주고 클라이언트가 프로바이더 에대한 데이터요청을 하면 자체 api서버가 대신 호출 해 주는건가요?

의견 추가하기