1. 개념
가. 용어정리
1) OAuth
•
OAuth(Open Authorization): 제 3의 서비스으로부터 특정 서비스 이용에 필요한 권한을 부여 받는 것입니다.
1) 인증 vs 권한
•
인증(Authentication): 스스로 주장하는 신원이 맞는지 확인합니다.
•
권한(Authorization): 원하는 정보를 얻도록 허용합니다.
2) 역할
•
Client: 나의 서비스(mine)
•
Resource Owner: 사용자(user)
•
Resource Server: 깃헙 데이터 서버, 구글 데이터 서버, 페이스북 데이터 서버 등
•
Authorization Server: 인증을 담당하는 서버, 깃헙 인증 서버
→ 작은 회사의 경우 Resource Server와 Authorization Server를 하나의 서버로 관리함
나. Access Token 관리
3) Session
Client Server의 DB 호출이 빈번하게 발생하므로 Client Server에 부담이 큰 방식
•
세션 관리
가) Access Token을 Client Server의 DB에 저장
나) API 호출에 따라 request에 포함된 Access Token의 유효성 검사
다) Access Token 갱신에 따라 DB에 저장된 Access Token 업데이트
•
세션방식의 인증 및 인가
가) API 요청에 따라 request에 포함된 Access Token이 Client Server의 DB에 존재하는지 확인
나) 두 정보를 비교하여 Access Token의 만료기간 확인
다) 유효하다면 DB에서 로그인 정보 조회하여 response로 전달
4) JWT
•
JWT 관리
가) JWT(Client Server에서 발급)를 Client side(Resource Owner)에 저장
나) Client Server는 API 호출에 따라 request에 포함된 JWT의 유효성 검사 및 유효 정보를 Resource Owner에게 전달
•
JWT의 인증 및 인가
가) API 요청에 따라 request에 포함된 JWT의 signature 확인
나) JWT의 payload에서 로그인 정보 추출하여 response로 전달
•
참고
→ JWT 토큰의 경우 외부에 공개해도 되는 정보의 경우, 개발자 도구 application 탭에서 local storage를 통해 토큰 정보로 확인할 수 있음
→ 해당 토큰을 JWT 사이트에서 복화화할 수 있음
나. Client 등록
1) 등록 과정
Resource Server에 Client의 서비스 등록
•
Client가 Resource Server에 접속하기 위해 사전 승인 또는 등록 절차를 거쳐야 함
•
등록 시에 필요한 정보는 Client ID, Client Secret, Authorized redirect URI
→ Client ID: Resource Server에서 각각의 Client를 식별하기 위한 식별자, 노출 O
→ Client Secret: 식별하기 위한 비밀번호, 노출 X
→ Authorized redirect URI: Resource Server에서 이 URI로 Authorized Code를 전달함. 이 URI 외의 다른 주소로 Resource Server에 요청이 가면 서버는 무시함
다. Resource Owner의 승인
Client의 서비스에 필요한 특정 Resource의 사용 권한을 Resource Owner로부터 승인 받는 과정
1) Resource Server에 Client 등록 완료 후
•
Client: Client Id, Client Secret 보관
•
Resource Server: Client Id, Client Secret, Redirect URL 보관
2) Resource Owner가 Client에 접속
•
Resource Owner가 Client에 접속하면
•
Client는 Resource Owner에게 Resource Server로 Redirect 유도
→ 로그인 버튼(또는 Resource Server의 자원 사용에 대한 승인 문구)
→ Client가 Resource Owner를 Redirect하면서, Client Id, Redirect URL, Resource Scope(Resource Server의 특정 자원) 세 가지 정보를 함께 요청
3) Resource Owner가 Resource Server로 Redirect
•
로그인이 되어 있지 않다면 Resource Owner에게 로그인 유도
•
로그인 성공 시 'Client의 Redirect 유도 방식'에 포함된 Client Id, Redirect URL이 Resource Server 내 저장된 값과 일치하는 지 확인
→ 일치하지 않다면 작업 중단
•
일치한다면 Resource Server는 Resource Owner를 대신하여 Client에게 Resource Scope에 대한 사용 권한 승인
→ 확인되면 Resource Server에 user id와 resource scope가 저장됨
라. Resource Server의 임시 승인
Resource Server에서 Client에 대해 Authorization Code를 발급하여 임시 승인하는 과정
1) Authorization Code 획득
•
Resource Server에서 Resource Owner에게 Redirection 유도
→ Redirection은 Client가 Resource Server에 등록한 Redirect URL
→ Redirection에 Authorization Code를 포함하여 전달
•
Resource Owner는 Client에게 Redirect 주소로 요청을 시도
→ 이 요청에 Authorization Code가 포함되어 Client에 저장됨
→ https://www.~~.~~/login?code=
2) Client → Resource Server 인증
•
Resource Owner를 제외하고 Client에서 Resource Server로 직접 요청
→ Client Secret, Authorization Code, Client Id, redirect URL 확인
→ Resource Server는 위의 네 가지 정보가 일치하는 지 확인
마. Access Token
Authorization Code를 제거하고 Access Token을 발급하는 과정
1) Access Token 생성
•
Resource Server에서 특정 user Id와 연관된 authorization Code를 제거
•
authorization Code 대신 Access Token 값 생성
2) Access Token 발급
•
Resource Server에서 Client에게 Access Token 전송
•
Client는 authorizatio Code를 지우고 Access Token 생성
바. API 호출 방법
Resource Server의 API 호출 방법 중 Authorization in HTTP Header 방식이 표준
1) Query Parameter
•
Access Token을 Query Parameter로 전달하는 방법
•
Query Parameter는 server log에 남기 때문에 선호되지 않는 방법
•
비표준
2) Authorization in HTTP Header
•
Header에 AccessToken을 전달하는 방법
•
보다 안전하기 때문에 표준 방식
사. Refresh token
1) Access Token의 수명
•
일반적으로 1~2시간, 길면 60일 정도의 수명이 있음
•
리프레쉬 토큰의 경우 만료시간이 상대적으로 긴 편임
→ 일반적으로 리프레쉬 토큰은 인증할 때만 사용하기 때문에 유출된 가능성이 매우 낮다
→ 리프레쉬 토큰의 만료기간이 지나면 다시 resource Owner가 인증을 해야함
2) Access Token 재발급
•
재발급 방법은 API마다 다를 수 있음
•
일반적으로 Access Token을 발급 받을 때, Refresh Token을 함께 발급 받음
•
Access Token이 만료되면 Refresh Token으로 요청을 하면 Access Token을 응답으로 받을 수 있음
•
Token 받는 방법 일반
image from RFC 6749 - The OAuth 2.0 Authorization Framework
2. 적용
가. 순수 토큰 활용(feat. GitHub)
1) Resource Server 임시승인
임시승인 코드는 일회성이므로 동일한 임시승인 요청 시 다른 임시 승인 코드가 발급됨
•
Client Server에서 Resource Server로 임시 승인 코드 요청
•
Client Server에서 redirect URI로 전달된 임시 승인 코드 받음
→ response 형태가 아니라 Resource Server에서 redirect되어 전달됨
→ redirect URI?code={임시 승인 코드}
2) Access Token 발급
•
Client Server에서 Resource Server로 Token 요청
→ POST, https://github.com/login/oauth/access_token + client_id + client_secret + code
→ response를 JSON 형태로 받기 위해 Header 추가
→ ex) accept: application/json
•
Resource Server에서 Token 전달
→ Response format
{
"access_token": "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",
"token_type": "bearer",
"scope": "user"
}
Bash
복사
3) Access Token 활용하여 로그인 구현
•
유저 정보 가져오기
→ Header에 토큰 추가
→ Authorization: token OAUTH-TOKEN
→ Authorization: token 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
•
Response
{
"login": "MJbae",
"id": 16694346,
"node_id": "MDQ6VXNlcjE2Njk0MzQ2",
"avatar_url": "https://avatars.githubusercontent.com/u/16694346?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/MJbae",
"html_url": "https://github.com/MJbae",
"type": "User",
"site_admin": false,
"name": "Manjin Bae",
}
Bash
복사
4) Access Token 활용하여 로그아웃 구현
나. JWT 활용(feat. GitHub)
1) AccessToken 획득
•
Client Front의 임시 승인 코드 획득(From Resource Server)
•
Client Server의 임시승인 코드 획득(From Client Front)
•
Client Server의 Access Token 획득(From Resource Server)
2) User 정보 획득
•
Client Server의 User 정보 획득(From Resource Server)
→ Access Token 활용
•
Client Server에서 User 정보를 JWT로 해싱처리
3) JWT 전달
•
Client Front의 JWT 획득(From Client Server)
Reference
•
OAuth와 JWT의 관계, https://swalloow.github.io/implement-jwt/