OAuth 2.0 을 구현하기 위해 알아야 할 것들 # Access Refresh Token
오늘은 OAuth를 구현하기 위해서 알아두어야 할 것에 대해서 정리해 보도록 하겠습니다.
1. OAuth
OAuth는 인터넷 표준화 기구인 IETF(Internet Engineering Task Force)에 의해 정의된 표준 프레임워크입니다.
3rd 파티 앱에서,
SNS서비스업체인 Resource를 가지고 있는 서버에 제한적으로 접근할 수 있는 방법에 대한 Framework를 정의한 것 인데요.
Google, Facebook, Kakao, Naver 등의 서비스 제공자들은,
OAuth를 통해 외부 애플리케이션에 사용자의 계정 데이터에 접근할 수 있는 권한을 안전하게 부여합니다.
이렇게 해서 사용자의 로그인 정보를 직접 제3의 애플리케이션에 제공하지 않고도,
해당 애플리케이션이 사용자의 정보에 접근할 수 있도록 허용해 줍니다.
OAuth를 이용하는 방법은 앱마다 다르겠지만,
유저 인증과 보안을 대신하는 수단으로 많이 사용하고 있습니다.
OAuth를 이용하면, 예전처럼 유저의 아이디와 비밀번호를 인증하고 그것에 대한 보안을 책임질 필요가 없습니다.
유저인증은 Google이나 FaceBook같은 큰 업체에게 맡기고,
이들 업체에서 AccessToken을 받아서, Google이나 FaceBook에 접근해서 인증을 받아 앱을 사용하면 됩니다.
이렇게 함으로서, 서비스 업체들은 비즈니스로직에 집중하며,
Google이나 Facebook같은 인증업체들의 id나 password를 저장시키지 않고 이용하면서,
허용된 범위안에서만 사용할수 있게 되었습니다.
1-1. Roles
OAuth2.0에서는 Role의 이름 들을 정의해놓고 있는데요.
Client는 저희 개발자들이 구현하는 클라이언트 앱으로 웹앱이나 안드로이드 앱을 가르키구요.
유저는 Resource Owner라고 합니다.
한가지 알아둘것은, OAuth2.0에서는 API서버와 인증서버를 분리하고 있는데요.
그래서 용어도 구분하고 있습니다.
Authorization Server는 Facebook, Google의 인증서버이구요.
Resource Server는 Facebook, Google의 API서버입니다.
예를 들어, Google 캘린더에서 일정을 받아오려면,
Google인증서버에서 AccessToken을 받아서,
그 토큰으로 Google의 캘린더 API서버에 접근해 받아와야 하는 구조로 되어 있습니다.
이에관한 구체적인 내용은 아래에서 다루도록 하겠습니다.
그럼, OAuth를 구현하기전에 가장 먼저 해야할 앱 등록부터 보도록 하겠습니다.
2. 앱 등록
OAuth를 사용하기 위해서 미리 해당 리소스를 제공하는 서버에 앱 정보를 등록해놓아야 합니다.
앱의 이름이나 필요로 하는 정보등을 기입해 줍니다.
등록을 하는 방식자체는 업체마다 다르지만, 등록을 마치면 대부분 아래의 정보를 전달해 줍니다.
구분 | 내용 |
ClientID | 등록된 클라이언트를 구분하기 위한 ID |
Client Secret | 클라이언트가 접속할 때 사용할 Secret Key 비밀번호로서 노출시 변경해 주어야 합니다. |
Redirect URI (콜백 URI) |
인증된 사용자를 redirect 시킬 URI |
3. OAuth Flow
OAuth를 이용하는 방식은 다음과 같은 Flow를 따르게 되는데요.
간단하게 생각하면 간단하지만, Flow를 보면 조금 복잡해 보일수도 있습니다.
2번의 앱등록과정은 이미 하였고, Redict Url주소의 페이지도 구현이 되어있다고 가정하고 보겠습니다.
조금 복잡하지만, 구글의 공식문서에 나오는 이미지를 먼저 쓰윽 보도록 하겠습니다.
무언가 생각보다 많은 단계를 거치게 되네요.
앱이 Google Server에 인증토큰을 요구하구요. -> 그럼 Authorization Code를 받습니다.
->이 Code를 가지고 Google의 Server에서 Token으로 교환을 받는데요. -> Response를 통해 App이 Token을 받게 됩니다.
-> 이 토큰을 가지고, 허용된 Scope내의 Google API들을 이용하는 것 입니다.
이해하기 쉽게, 예를 들어보도록 하겠습니다.
- 사용자가 로그인창에 접근하여 FaceBook 로그인하기 버튼 클릭
- FaceBook의 UI에서 로그인과 비밀번호 입력
- FaceBook에 로그인 되면, 해당 앱에서 필요로 하는 권한들을 유저에게 확인하는 UI를 보여줌.
- 유저가 확인버튼을 클릭시, Redirect Url과 Authorization 코드를 발급받아 User에게 전달
- 저희가 개발한 앱서버는 Autorization 코드를 Redirect Url을 통해서 전달받아서, FaceBook서버에 ID와 SecretKey그리고 Authorization코드를 가지고 접근합니다.
- 이제 FaceBook서버는 전달받은 정보를 바탕으로 Acces Token과 Refresh Token을 발급
- 앱 서버에서는 발급받은 AccessToken을 저장
- 저장된 AccessToken을 가지고, Facebook에 허용된 Scope내의 API명세에 맞게 사용함
API를 부르는 부분에 대한 가이드는 SNS서비스 업체들마다 다 다른데요.
Google Identity에 자세하게 잘 나와있으니 보시면 좋을 것 같습니다.
HTTP헤더에 "Authorization: Bearer"라는 이름을 사용하네요.
헤더를 사용하지 않고, query String 방식을 사용할 때는 https만 사용해야 한다고 적혀있네요.
4. Access Token
4-1. Acces Token
위에서 언급한 Access Token에 대해서 다시 한번 짚어보고 가겠습니다.
Google이나 Facebook의 로그인과정을 거치면서, 저희가 만든 앱은 유저의 비밀번호를 알지 못합니다.
대신, Access Token을 Google이나 FaceBook으로부터 부여받아서,
유저가 허락한 범위안에서 서비스에 유저대신 접근할 수 있는 것 이지요.
이러한 방식은 문제가 발생했을 때, Token의 유효성을 만료시키기만 하면 되기 때문에,
빠르게 대응할 수 있는 장점이 있습니다.
그리고 유저가 비밀번호를 바꾸게 되더라도 Access Token은 유효하게 할 수 있습니다.
(물론 일부 앱들은 유저가 비밀번호를 바꾸면, Access Token도 만료되도록 하거나, 만료시킬지 유저에게 물어봅니다.)
또한, AccessToken은 제공하는 업체마다 그것의 유효기간을 가지고 있어서, 무한정 그것을 가지고 사용할 수 없습니다.
4-2. AccessToken의 저장
OAuth를 구현하는 입장에서는 Google이나 Facebook같은 업체에서 Token을 받았을 경우 고민해야 할 부부이 있습니다.
받은 Access Token을 가지고, Google등의 API서버에 접근해야할 경우에 어떻게 그 Token을 저장하고 있다가 전송할거냐 입니다.
5. Refresh Token
5-1. Refresh Token
위의 Flow에서 AccessToken과 함께 Refresh Token을 발급받은 것을 보셨을 텐데요.
위에서 본, Access Token은 유효기간이 짧은 편 입니다.
아래는 국내의 카카오로그인 기능의 토큰 유효기간입니다.
Private한 Android이나 iOS같은 경우, 12시간으로 꽤 긴 편이라고 할 수 있습니다.
그런데, 유효기간이 끝날때마다 사용자에게 로그인과 패스워드 인증을 받으면 유저가 불편해 하겠지요.
아마 더이상 저희가 만든앱을 이용하지 않게 될수도 있습니다.
그래서 사용하는 게 이 RefreshToken입니다.
AccessToken처럼 SNS서버의 API에 바로 접근할 수 있는 것은 아니지만,
Refresh Token을 이용해서 SNS서버에 접근해서 유효한 Access Token을 새로 받아서 갱신할 수 있습니다.
Google의 경우는 아래와 같이 request를 하면,
JSON타입으로 accessToken을 전달해 주게 되네요.
Refresh Token의 경우 Access Token보다는 유효기간이 길지만 없지는 않습니다..
Google의 경우 6개월 지난 RefreshToken은 유효기간이 끝나서 사용할 수 없게 되어 있습니다.
그리고 앱에 대한 Access를 유저가 직접 취소한 경우도 있는데요.
이런경우도 Refresh Token은 유효하지 않게 됩니다.
5-2. Refresh Token의 저장
Refresh Token의 경우 클라이언트에 저장하는 것은 위험할 수 있습니다.
일단 유효기간이 매우 길기 때문에, 문제가 발생하는 것을 알고있어도 대응하기가 어려울 수 있구요.
Google같은 경우는 첫 로그인시 발행한 RefreshToken을 다시로그인할 때도 만료하기 전에는 사용하도록 하고 있으므로,
반드시 서버에 저장해 둘 필요가 있습니다.
따라서 가장 안전한 서버에 저장하는 것이 좋은데요.
클라이언트에 서버에서 불러올 수 있는 index값을 해쉬값등으로 변형해 저장해서 사용하는 것이 방법일 수 있습니다.
(참조한 내용입니다.)
6. 소셜로그인 기능의 사용에 관하여
처음 시작하는 스타트업에게,
소셜 로그인기능은 유저들에게 가입의 부담을 줄여주는 아주 좋은 방법입니다.
사실, 처음 들어본 서비스에 아이디를 만들고, 비밀번호까지 생각해서 입력한다는 것은 큰 허들이 아닐 수 없습니다.
이렇게 좋은 소셜로그인기능이지만,
자원을 효율적으로 써야하는 스타트업에게 소셜로그인기능이 만능은 절대 아닙니다.
왜냐하면, 사용자가 받은 Token을 결국에는 DB에 저장해 놓고 사용해야 하기 때문입니다.
그래도, 예전처럼 id와 Password를 받아서 DB에 검증하는 것보다는 훨씬 효율적일 것 같습니다.
AccessToken이 유효한지 확인
-> 유효하다면 서버에 보내서 유효성을 확인
-> 유효하지 않다면 RefreshToken을 발급
7. OAuth2.0 공식문서
OAuth2.0 공식적인 문서는 아래와 같습니다.
>> tools.ietf.org/html/rfc6749
관심이 있으시다면 좀 더 깊숙히 읽어보시구요.
이상으로 OAuth에 대한 글을 마치도록 하겠습니다.