본문 바로가기

기술

Mobile App을 위한 OAuth 2.0 인증 서버 구조

영어 머리아파...

 

들어가며

이 글은 OAuth 2.0과 4가지 인증 방식, 그리고 토큰 인증 방식에 대한 개념을 알고 계신다고 가정하고 쓴 글입니다. 헷갈리는 개념이 있을 경우 다음 링크들을 참고하길 바랍니다. 또한 이 글은 스택오버플로우의 답변을 정리한 글입니다.

 

OAuth와 춤을

쉽게 알아보는 서버 인증 1편(세션/쿠키, JWT)

쉽게 알아보는 서버 인증 2편(Access Token + Refresh Token)

OAuth 2.0, Grant Type 개념 정리

 

Authorization Code vs. Implicit

모바일 App을 위한 Web API를 만들 때 OAuth 2.0의 어떤 Grant Type을 사용해야 좋을까요? 만약 클라이언트가 웹이라면 망설임 없이 Authorization Code Grant Type을 사용할 것입니다. 모바일 App을 위해 Implicit Grant Type이 권장되지만, 이를 사용할 경우 Authorization Code Grant Type을 사용할 경우보다 보안이 취약합니다. 따라서 Refresh Token 역시 사용할 수 없습니다. 하지만, 그렇다고 Access Token 의 생명 주기를 길게 줄 수도 없고, 그렇다고 모바일 사용자가 항상 앱을 사용할 때마다 로그인을 하여 새로 Access Token을 받게 하기도 꺼려집니다. 좋은 방법이 없을까요?

 

중요한 것은 어떤 방법을 사용하든, 다음 가이드는 한 번 읽어보시길 추천합니다: https://tools.ietf.org/html/rfc8252

Implicit

위 RFC 문서의 Section 8.2에 따르면, Implicit은 일반적으로 브라우저에서 권한 부여에 대한 요청을 실행하고 URI 기반의 inter-app 통신을 통해 그에 대한 응답을 받는 방식으로 작동합니다.하지만, Implicit 방식은 중간의 가로채기 공격을 PKCE를 통해 보호할 수 없습니다. (PKCE를 사용하여 공용 클라이언트의 통신 보안) 따라서 네이티브 앱에서의 Implicit 방식의 사용을 추천하지 않습니다.

 

또한 Implicit 방식을 통한 Access Token은 사용자와의 상호작용 없이 갱신할 수 있으므로, Refresh Token을 발급하여 Access Token을 갱신할 수 있도록 하는 Authorization Code 방식이 더 좋은 방안입니다.

Authorization Code

Authorization Code를 사용하게 된다면 redirect url을 포함하여 client secret 등의 정보를 제공해야 합니다. 이때, 한 가지 접근 방법은 프록시 웹 서버를 통해 client secret을 제공하여 토큰을 요청하는 것입니다. client secret은 디바이스의 배포된 앱에 저장하면 안 됩니다. 절대 다운로드 가능한 앱, 혹은 클라이언트의 자바스크립트 코드와 같이 배포된 코드에 client secret을 저장하지 마십시오.

 

Authorization Code 방식은 웹 서비스를 갖고 있는 앱들에게 추천됩니다. 이는 앱의 client secret을 사용하여 서버-서버 간의 통신을 요구합니다.

결론

Best한 방법은 없습니다. 필요에 따라 위험을 감수하고 서비스에 알맞는 선택을 하시는 것이 좋습니다.

 

그래도 현재 업계에서 가장 좋은 방법은 Authorization Code 방식을 사용하는 것이라고 합니다. 이때, 네이티브 앱으로부터 분리된 다른 브라우저를 사용하여 외부에서 사용자가 인증을 하도록 하는 것이 안전합니다. 이를 통해 client secret도 보호할 수 있고, 앱이 브라우저의 쿠키 저장소나 다른 페이지 내용을 바꾸지 못하도록 할 수 있다고 합니다.

추천 글

https://auth0.com/blog/oauth-2-best-practices-for-native-apps/

https://www.oauth.com/oauth2-servers/oauth-native-apps/