인증 코드 흐름

김서연·2024년 9월 19일

Spotify API

목록 보기
2/5

Authorization Code Flow (인증 코드 흐름)

Authorization code flow는 사용자가 한 번만 권한을 부여하는 장기 실행 애플리케이션(예: 웹 및 모바일 애플리케이션)에 적합합니다.

모바일 애플리케이션이나 클라이언트 비밀을 안전하게 저장할 수 없는 다른 유형의 애플리케이션에서 authorization code flow를 사용하는 경우, PKCE 확장을 사용하는 것이 좋습니다. 이 흐름을 올바르게 구현하는 방법에 대해 알아보려면 계속 읽어주세요.

다음 다이어그램은 authorization code flow가 어떻게 작동하는지를 보여줍니다:

Authorization Code Flow

사전 요구 사항

이 가이드는 다음을 가정합니다:

  • 권한 부여 가이드를 읽었습니다.
  • 앱 가이드를 따라 앱을 생성했습니다.

예시

Authorization Code flow를 구현한 예시 앱은 GitHub의 web-api-examples 리포지토리에서 확인할 수 있습니다.

사용자 권한 요청

첫 번째 단계는 사용자로부터 권한을 요청하여 애플리케이션이 사용자를 대신해 Spotify 리소스에 접근할 수 있도록 하는 것입니다. 이를 위해, 애플리케이션은 /authorize 엔드포인트에 다음과 같은 매개변수를 포함한 GET 요청을 빌드하고 전송해야 합니다:

쿼리 매개변수중요도
client_id필수애플리케이션 등록 후 생성된 Client ID입니다.
response_type필수"code"로 설정합니다.
redirect_uri필수사용자가 권한을 부여하거나 거부한 후 리디렉션할 URI입니다. 이 URI는 애플리케이션 등록 시 입력한 Redirect URI 허용 목록에 포함되어야 합니다. 대소문자, 종료 슬래시 등도 정확히 일치해야 합니다.
state선택 사항교차 사이트 요청 위조(CSRF) 공격에 대한 보호를 제공합니다. RFC-6749를 참조하세요.
scope선택 사항스코프의 공백으로 구분된 목록입니다. 스코프가 지정되지 않으면, 일반적으로 Spotify 플레이어에서 공개적으로 사용 가능한 정보에만 접근 권한이 부여됩니다.
show_dialog선택 사항사용자가 이전에 애플리케이션을 승인했더라도 다시 승인하도록 할지 여부를 지정합니다. 기본값은 false이며, true로 설정하면 사용자는 승인 없이 자동으로 리디렉션되지 않고 애플리케이션을 다시 승인해야 합니다.

다음은 Express 프레임워크를 사용하여 인증 요청을 시작하는 /login 메소드를 구현한 JavaScript 코드 예제입니다:

var client_id = 'CLIENT_ID';
var redirect_uri = 'http://localhost:8888/callback';

var app = express();

app.get('/login', function(req, res) {
  var state = generateRandomString(16);
  var scope = 'user-read-private user-read-email';

  res.redirect('https://accounts.spotify.com/authorize?' +
    querystring.stringify({
      response_type: 'code',
      client_id: client_id,
      scope: scope,
      redirect_uri: redirect_uri,
      state: state
    }));
});

이 요청이 처리되면 사용자는 user-read-privateuser-read-email 스코프에 대한 접근 권한을 승인하라는 대화창을 보게 됩니다.

Spotify의 OAuth 2.0 서비스는 요청된 스코프의 세부 정보를 사용자에게 보여줍니다. 사용자가 로그인하지 않은 경우 Spotify 자격 증명을 사용해 로그인하라는 메시지가 표시됩니다. 사용자가 로그인하면 해당 스코프에서 정의된 데이터나 기능에 대한 접근 권한을 승인하도록 요청받습니다.

마지막으로 사용자는 지정한 redirect_uri로 다시 리디렉션됩니다. 사용자가 요청을 승인하거나 거부한 후, Spotify OAuth 2.0 서비스는 사용자를 redirect_uri로 다시 리디렉션합니다. 이 예시에서는 https://localhost:8888/callback으로 리디렉션됩니다.

응답

사용자가 요청을 승인하면 redirect_uri를 통해 다음 두 가지 쿼리 매개변수가 포함된 콜백이 애플리케이션으로 전송됩니다:

쿼리 매개변수
code액세스 토큰으로 교환할 수 있는 인증 코드입니다.
state요청 시 제공된 state 매개변수의 값입니다.

예시:

https://my-domain.com/callback?code=NApCCg..BkWtQ&state=34fFs29kd09

사용자가 요청을 승인하지 않거나 오류가 발생한 경우 응답 쿼리 문자열에는 다음 매개변수가 포함됩니다:

쿼리 매개변수
error권한 부여가 실패한 이유입니다. 예: "access_denied"
state요청 시 제공된 state 매개변수의 값입니다.

예시:

https://my-domain.com/callback?error=access_denied&state=34fFs29kd09

두 경우 모두, 애플리케이션은 리디렉션 URI에서 수신한 state 매개변수를 원래 authorization URI에 제공된 state 매개변수와 비교해야 합니다. 일치하지 않는 경우 요청을 거부하고 인증 흐름을 중단해야 합니다.

액세스 토큰 요청

사용자가 요청을 승인한 경우, 애플리케이션은 이제 인증 코드를 액세스 토큰으로 교환할 준비가 된 것입니다. 이를 위해 /api/token 엔드포인트에 POST 요청을 전송해야 합니다.

이 POST 요청의 본문에는 다음 매개변수가 application/x-www-form-urlencoded 형식으로 포함되어야 합니다:

본문 매개변수중요도
grant_type필수이 필드에는 "authorization_code" 값을 포함해야 합니다.
code필수이전 요청에서 반환된 인증 코드입니다.
redirect_uri필수이 매개변수는 검증 목적으로만 사용됩니다(실제 리디렉션은 없습니다). 인증 코드를 요청할 때 제공된 redirect_uri 값과 정확히 일치해야 합니다.

이 요청은 다음과 같은 HTTP 헤더를 포함해야 합니다:

헤더 매개변수중요도
Authorization필수클라이언트 ID와 클라이언트 비밀 키를 포함한 Base64 인코딩된 문자열. 형식은 다음과 같습니다: Authorization: Basic <base64로 인코딩된 client_id:client_secret>
Content-Type필수application/x-www-form-urlencoded으로 설정합니다.

이 단계는 이전 단계에서 설명한 요청의 콜백 내에서 구현됩니다:

app.get('/callback', function(req, res) {
  var code = req.query.code || null;
  var state = req.query.state || null;

  if (state === null) {
    res.redirect('/#' +
      querystring.stringify({
        error: 'state_mismatch'
      }));
  } else {
    var authOptions = {
      url: 'https://accounts.spotify.com/api/token',
      form: {
        code: code,
        redirect_uri: redirect_uri,
        grant_type: 'authorization_code'
      },
      headers: {
        'content-type': 'application/x-www-form-urlencoded',
        'Authorization': 'Basic ' + (new Buffer.from(client_id + ':' + client_secret).toString('base64'))
      },
      json: true
    };
  }
});

응답

요청이 성공하면 응답에는 200 OK 상태와 함께 다음과 같은 JSON 데이터가 포함됩니다:

타입설명
access_tokenstring향후 호출 시 제공할 수 있는 액세스 토큰, 예: Spotify Web API 서비스에서 사용.
token_typestring액세스 토큰의 사용 방식: 항상 "Bearer".
scopestring이 액세스 토큰에 부여된 스코프의 공백으로 구분된 목록.
expires_inint액세스 토큰이 유효한 시간(초 단위).
refresh_tokenstring액세스 토큰을 갱신하는 방법에 대한 자세한 내용은 토큰 갱신 가이드를 참조하세요.

다음 단계는?

축하합니다! 이제 새로 발급된 액세스 토큰을 사용할 준비가 되었습니다! 액세스 토큰을 사용하여 API 호출을 하는 방법에 대해 자세히 알아보려면 access token 가이드를 확인하세요.

액세스 토큰이 만료된 경우, 사용자에게 다시 권한을 요청하지 않고 새로운 토큰을 발급받는 방법은 refresh token 가이드를 참조하세요.

profile
https://velog.io/@tidchron 으로 이전

0개의 댓글