블로그 이전
https://skitttles.me/posts/oauth_concept/
PortSwigger의 글을 번역하였습니다 😀
OAuth 2.0("Open Authorization 2.0")는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 표준입니다.
OAuth를 이용하면 아래 그림과 같이 네이버, 카카오오, 페이코 등 타 서비스를 이용하여 로그인을 할 수 있습니다. 또한 가입 시에도 타 서비스를 이용하여 정보를 제공하고 가입을 할 수도 있습니다.

OAuth를 이용하여 정보 요청 시에는 기본적으로 아래와 같은 과정을 거치게 됩니다.
클라이언트 어플리케이션이 OAuth 서비스 제공자에게 필요한 정보 및 각종 파라미터를 요청을 보냅니다.
OAuth 서비스 제공자는 리소스 오너에게 로그인과 권한/정보 제공 동의 요청을 합니다.
리소스 오너가 동의 시 OAuth 서비스 제공자자는 클라이언트 어플리케이션**에게 인증 코드 또는 토큰을 부여하여 이후에 정보 요청 및 검증에 사용되게 됩니다.
인증 코드의 경우, 클라이언트 어플리케이션과 OAuth 서비스 제공자 간 서버 대 서버 통신으로 토큰 부여 과정을 거치게됩니다.
이후에는 클라이언트 어플리케이션이 OAuth 서비스 제공자에게 API를 통해 정보를 요청하고 받을 수 있게됩니다.
위와 같은 과정을 거치는 OAuth에는 2가지 권한 부여 방법이 존재합니다.

① 승인 요청 : 클라이언트 어플리케이션이 특정 사용자 데이터에 접근할 수 있는 권한을 /authorization 과 같은 엔드 포인트로 요청합니다. 보통 요청 URL은 아래와 같은 형식을 가집니다.
GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=code&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1 Host: oauth-authorization-server.com
각 파라미터의 용도는 아래와 같습니다.
code 값을 부여합니다.② 사용자 로그인 및 동의 : 사용자를 인증하기 위해 로그인을 요청하고 요청하는 권한과 정보에 대해 동의를 요청합니다.
③ 승인 코드 부여 : 사용자가 동의하면 OAuth 서비스 제공자는 사용자의 브라우저를 권한 부여 요청의 redirect_uri 에 지정된 엔드포인트로 리디렉션 시킵니다. 요청 URL에는 승인 코드가 매개 변수로 포함되며 구성에 따라 승인 요청과 동일한 값의 state 매개 변수를 보낼 수도 있습니다.
GET /callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com
④ 엑세스 토큰 요청 : 클라이언트 어플리케이션이 승인 코드를 받으면 액세스 토큰으로 교환합니다. 이를 위해 OAuth 서비스의 /token 엔드포인트에 서버 대 서버 POST 요청을 보냅니다. 서버 대 서버 요청은 외부에서는 보거나 변조할 수 없습니다.
POST /token HTTP/1.1 Host: oauth-authorization-server.com
…
client_id=12345&client_secret=SECRET&redirect_uri=https://client-app.com/callback&grant_type=authorization_code&code=a1b2c3d4e5f6g7h8
각 파라미터의 내용은 아래와 같습니다.
⑤ 엑세스 토큰 부여 : 클라이언트 어플리케이션이 유효하다면, 서버에서 아래와 같이 토큰을 부여받습니다.
{
"access_token": "z0y9x8w7v6u5",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile",
…
}
⑥ API 요청 (정보 요청) : 클라이언트 어플리케이션은 Authorization: Bearer 헤더에 엑세스 토큰을 담아 /userinfo 엔드포인트에 사용자 정보를 요청합니다. 이때의 엔드포인트는 어플리케이션에 따라 다를 수 있습니다.
GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5
⑦ 정보 전송 : 사용자의 정보를 가진 리소스 서버는 받은 토큰이 유효하면 요청받은 정보를 클라이언트 어플리케이션으로 전송합니다.
{
"username":"carlos",
"email":"carlos@carlos-montoya.net",
…
}

① 승인 요청 : 클라이언트 어플리케이션이 특정 사용자 데이터에 접근할 수 있는 권한을 /authorization 과 같은 엔드 포인트로 요청합니다. 보통 요청 URL은 아래와 같은 형식을 가집니다.
GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=token&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1 Host: oauth-authorization-server.com
각 파라미터의 의미는 승인 코드 부여 방식과 동일하며 암시적 부여 방식에서는 response_type을 token 설정합니다.
② 사용자 로그인 및 동의 : 사용자를 인증하기 위해 로그인을 요청하고 요청하는 권한과 정보에 대해 동의를 요청합니다.
③ 액세스 토큰 부여 : 사용자가 동의하면 OAuth 서비스 제공자는 사용자의 브라우저를 권한 부여 요청의 redirect_uri 에 지정된 엔드포인트로 리디렉션시킵니다. 요청 URL에는 액세스 토큰이 URL 조각 형식으로 포함되어 있습니다. 액세스 토큰은 URL 조각으로 전송되므로 클라이언트 어플리케이션 측에서는 알 수 없으며 사용자는 JavaScript 등 을 이용하여 브라우저 측에서 엑세스 토큰을 파싱하여 사용해야 합니다.
승인 코드 부여 방식과는 달리 서버 대 서버 통신이 아니므로 액세스 토큰이 사용자 브라우저에 노출됩니다.
GET /callback#access_token=z0y9x8w7v6u5&token_type=Bearer&expires_in=5000&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com
④ API 요청 (정보 요청) : 승인 코드 부여 방식과 동일한 패킷으로 요청을 하나, 사용자 브라우저 측에서도 요청이 발생할 수 있습니다.
GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5
⑤ 정보 전송 : 사용자의 정보를 가진 리소스 서버는 받은 토큰이 유효하면 요청받은 정보를 클라이언트 어플리케이션으로 전송합니다. 승인 코드 부여 방식과 동일합니다.