OAuth Grant Type - Authorization Code, Implict

kwak woojong·2023년 1월 11일
0
post-thumbnail

최근 OAuth 리소스 서버를 만드려고 하고 있다.

로또는 끝났냐고?

그거 로그인 기능 만들까 하다가 OAuth 적용을 해야 내가 공부가 되지 않을까 싶어서 그거 하는 중

OAuth으로 인증 및 권한을 위임 한다. 그 위임 방법이 grant type이라 하겠다.

즉 클라이언트에서 토큰을 어떻게 가지고 올래? 라는 뜻


이미 예전에 적어놨었음 근데 좀 더 깊게 파보자

grant type은 국룰로 한 4개 정도로 정해져 있다. 클라이언트나 서버를 어떻게 구성했냐에 따라 다르게 사용한다.

  1. Authorization Code
  2. Implicit
  3. password
  4. Client credentials

이 4가지로 구분 된다. 대부분은 1번 방식을 사용한다는 듯. 여기선 1번과 2번만 살펴보자


1. Authorization Code

1. 서비스 사용 요청

이건 뭐 이용자가 요청하는거니까 걍 넘기고

2. Authorization Code 요청

클라이언트가 인증 서버에게 권한 요청을 특정 엔드포인트에 한다.
이 엔드포인트 매핑은 제공 업체마다 다를 수 있음.
스프링 OAuth 서버도 기본 제공하는 api가 있을거임

/oauth/authoriza?response_type=code&client_id=foo&redirect_uri={example.oauth.server.com}&scope=블라블라&state=1q2w3e~!

대충 이런 식일거다.

response_type : Authorization Code 방식이므로 응답 값은 code로 들어와야 한다.
client_id : 클라이언트의 고유 식별자를 뜻한다.
redirect_uri : 인증 코드를 클라이언트에 보낼 때 사용자의 브라우저가 리다이렉션 되야 하는 uri다. 콜백 uri 혹은 콜백 엔드포인트라고도 한다.
scope : 액세스 하려는 사용자 데이터의 범위를 말한다. 사용자가 동의한 범위의 scope만이 액세스 토큰에 넣는다.
state : 클라이언트에서 랜덤 값을 저장해서 보낸다. 서버는 응답할 때 이 값을 정확하게 반환해야 한다. 이 매개변수는 엔드포인트에 대한 요청이 OAuth 요청을 시작한 사람 즉 리소스 오너와 동일한지 확인하는 값이다. csrf 공격을 차단하기 위한 수단으로 쓰겠지?

필수 값은 다아연히 response_type, client_id다 나머진 선택이나 state는 권장사항임.

3. 로그인

따지면 동의를 얻는 부분이라 할 수 있겠다. 구글 로그인을 사용한다고 했을 때, 우리 휴대폰으로 "야 이거 니가 요청한거 맞냐?" 뭐 이런거 오잖아? 그런거랑 비슷한거지
즉 2번에 Code 요청이 정상적으로 잘 이루어질 경우, 동의하니? 화면을 보게 된다.
보통 한 번 동의를 해두면 이후엔 안해도 된다.

4. Authorization Code 응답

3에서 리소스 오너가 ㅇㅋㄷㅋ 하면 인증 서버에선 인증 코드를 보내준다. 이게 바로 Authorization Code인 거시다.
3에서 ㅇㅋ 하면 2에서 정해둔 redirect_uri로 사용자의 브라우저는 리다이렉션 된다. 이 때 get 요청이 나갈 땐 파라미터로 인증 코드랑 state가 나간다.

GET /bar?code=abcdefg123&state=1q2w3e~! HTTP/1.1
Host : test.com

대충 이런 식임 인가코드는 1회용이다. 동일한 인가코드로 액세스 토큰을 요청할 시 무적권 실패한다.
인가 코드는 보안적인 이유로 빠르게 사용해야함. 그래서 보통 만료시간을 10분으로 제한 하도록 권장한다칸다.
자 이제 인가코드가 들어왔으니 클라이언트는 액세스 토큰을 요청해야 한다.

5. 액세스 토큰 요청

클라이언트는 Post를 써서 인증 서버에 액세스 토큰을 요청한다.
이를테면

POST /token HTTP/1.1
Host : example.com

client_id=foo&client_secret={secret}&redirect_uri={example.oauth.server.com}&grant_type=authorization_code&code=abcdefg123

client_secret이 드디어 나왔다.
구글 api를 써보면 알겠지만 신청할 때 단 1번 시크릿을 알려준다. 외우지도 못하니까 잘 적어놔야함.
그걸 여기서 쏴줘야 한다.
그리고 당연히 grant_type는 authorization_code고
4번에서 받은 code를 여기서 똑같이 써준다.

6. 액세스 토큰 전달

인증 서버가 토큰을 만들어서 잘 준다.
클라이언트는 이걸 또 저장해서 리소스 서버에 요청을 해야겠지?

7. 자원 요청 (api 호출)

클라이언트가 드디어 리소스 서버에 자원을 요청할 수 있다.

GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization : Bearer 어쩌구저쩌꾸꺼쩌쩌

내가 지금 만들고 있는 OAuth 서버는 걍 리소스 서버랑 인증서버랑 통합해서 할거다. 귀찮음

8. 자원 전달 (응답)

그럼 걍 데이터 보내주면 끝!

클라이언트는 이걸 이용해서 로그인 잘 해두면 된다.


2. Implict (암묵적 승인)

1번 인증 코드 방식에서 인증 코드 와리가리를 빼면 얘다.

1. 사용 요청

나 sns 로그인 할꺼야

2. 접근 권한 요청

코드 방식과 거의 비슷하다 여기까진! 근데 코드를 요청하는게 아니라 토큰을 요청함

/oauth/authoriza?response_type=token&client_id=foo&redirect_uri={example.oauth.server.com}&scope=블라블라&state=1q2w3e~!

다른건 다 똑같은데 response_type이 토큰임에 주목하자

3. 로그인

사용자가 로그인 하겠다고 ㅇㅋㄷㅋ 하는거다.

4. 액세스 토큰 전달

여기서 바로 클라이언트에게 액세스 토큰을 준다.
redirect_uri로 파라미터로 토큰을 전달한다

GET /callback#access_token=z0y9x8w7v6u5&token_type=Bearer&expires_in=5000&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com

이케이케 한다.

5. 자원 요청 (api 요청)

똑같음

GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization : Bearer 어쩌구저쩌꾸꺼쩌쩌

6. 자원 전달

똑같음


흐름은 대부분이 이런 형식이다.

다만 리소스 서버랑 인증 서버가 통합일 경우도 있고, 응답이 Json으로 오는지 다른거로 오는지 업체마다 다를 수 있음

상기 Authorization Code의 흐름을 기준으로 설계를 한다면, 암묵적 방법 역시 쉽게 할 수 있을 것!

참고 사이트
https://portswigger.net/web-security/oauth/grant-types
https://kimdoky.github.io/oauth/2019/05/01/oauth-serverside-flow/

profile
https://crazyleader.notion.site/Crazykwak-36c7ffc9d32e4e83b325da26ed8d1728?pvs=4<-- 포트폴리오

0개의 댓글

관련 채용 정보