메인 콘텐츠로 건너뛰기

앱 전용 인증 및 OAuth 2.0 베어러 토큰

X는 특정 사용자가 아니라 애플리케이션 자체를 대신해 인증된 요청을 보낼 수 있는 기능을 제공합니다. X의 구현은 OAuth 2 사양Client Credentials Grant 플로우를 기반으로 합니다. 애플리케이션 전용 인증은 사용자 컨텍스트를 포함하지 않으며, 애플리케이션이 자체 권한으로 API 요청을 수행하는 인증 방식입니다. 이 방법은 공개 정보에 대한 읽기 전용 액세스만 필요한 개발자를 위한 것입니다. 앱의 컨슈머 API 키를 사용하거나 앱 전용 액세스 토큰(베어러 토큰)을 사용해 애플리케이션 전용 인증을 수행할 수 있습니다. 이는 X API에 대해 보낼 수 있는 요청이 인증된 사용자 컨텍스트를 요구하지 않아야 함을 의미합니다. 애플리케이션 전용 인증으로 다음과 같은 작업을 할 수 있습니다:
  • 사용자 타임라인 가져오기
  • 모든 계정의 친구 및 팔로워 액세스
  • 리스트 리소스 액세스
  • 트윗 검색
사용자를 대신하여 요청을 보내려면 PKCE가 포함된 OAuth 1.0a 또는 OAuth 2.0 Authorization Code Flow만 필요하다는 점에 유의하세요. API reference 페이지에는 각 API를 사용하기 위해 필요한 인증 방법이 설명되어 있습니다. 다음을 수행하려면 액세스 토큰이 포함된 사용자 인증, 즉 사용자 컨텍스트가 필요합니다:
  • 트윗 또는 기타 리소스 게시
  • 사용자 검색
  • 모든 지오 엔드포인트 사용
  • 다이렉트 메시지 또는 계정 자격 증명 액세스
  • 사용자의 이메일 주소 가져오기

인증 플로우

이 방법을 사용하려면 앱 전용 액세스 토큰(일명 베어러 토큰)이 필요합니다. POST oauth2/token 엔드포인트에 consumer key와 secret을 전달해 앱 전용 액세스 토큰(베어러 토큰)을 발급받을 수 있습니다.  애플리케이션 전용 인증 플로우는 다음과 같습니다:
  • 애플리케이션이 consumer key와 secret을 특수 방식으로 인코딩해 자격 증명 세트를 만듭니다.
  • 애플리케이션이 POST oauth2/token 엔드포인트로 요청을 보내 해당 자격 증명을 앱 전용 액세스 토큰으로 교환합니다.
  • REST API에 접근할 때 애플리케이션은 앱 전용 액세스 토큰으로 인증합니다.
요청에 서명할 필요가 없으므로, 이 방식은 표준 OAuth 1.0a 모델보다 훨씬 간단합니다.

앱 전용 인증에 대해

토큰은 비밀번호입니다 consumer key와 secret, 그리고 앱 전용 액세스 토큰(베어러 토큰) 자체는 애플리케이션을 대신해 요청을 수행할 수 있는 권한을 부여합니다. 이 값들은 비밀번호만큼 민감한 정보로 취급해야 하며, 신뢰할 수 없는 대상과 공유하거나 배포해서는 안 됩니다. SSL 필수 모든 요청(토큰을 발급받고 사용하는 경우 모두)은 반드시 HTTPS 엔드포인트를 사용해야 합니다. TLS를 사용하여 X API에 연결에 설명된 모범 사례를 따르세요 — 피어는 항상 검증되어야 합니다. 사용자 컨텍스트 없음 앱 전용 인증으로 요청을 보낼 때는 “현재 사용자”라는 개념이 없습니다. 따라서 POST statuses/update와 같은 엔드포인트는 앱 전용 인증으로는 동작하지 않습니다. 사용자를 대신해 요청을 보내는 방법은 OAuth 사용을 참고하세요. 요청 한도 애플리케이션에는 두 가지 유형의 요청 한도 풀(pool)이 있습니다. 사용자 컨텍스트(액세스 토큰 사용)로 사용자를 대신해 수행되는 요청은 앱 전용 인증에서 사용하는 것과는 다른 요청 한도 컨텍스트에서 차감됩니다. 즉, 사용자를 대신해 수행되는 요청은 앱 전용 인증을 통해 사용 가능한 요청 한도에서 차감되지 않으며, 앱 전용 인증을 통해 수행되는 요청도 사용자 기반 인증에서 사용하는 요청 한도에서 차감되지 않습니다. API 요청 한도에 대해 더 알아보고 한도 검토를 확인하세요.

앱 전용 요청 보내기

1단계: consumer key와 secret 인코딩하기 앱의 consumer key와 secret을 자격 증명으로 인코딩해 베어러 토큰을 얻는 절차는 다음과 같습니다:
  1. RFC 1738에 따라 consumer key와 consumer secret을 URL 인코딩합니다. 작성 시점 기준으로는 이 작업이 실제로 consumer key와 secret을 변경하지 않지만, 향후 해당 값의 형식이 바뀔 가능성에 대비해 이 단계를 수행해야 합니다.
  2. 인코딩된 consumer key, 콜론 문자 ”:” 및 인코딩된 consumer secret을 하나의 문자열로 연결합니다.
  3. 이전 단계의 문자열을 Base64 인코딩합니다.
아래는 이 알고리즘의 결과를 보여 주는 예시 값입니다. 이 페이지에서 사용된 consumer secret은 테스트용이며 실제 요청에는 작동하지 않습니다.
Consumer keyxvz1evFS4wEEPTGEFPHBog
Consumer secretL8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
RFC 1738 encoded consumer

key (does not change)
xvz1evFS4wEEPTGEFPHBog
RFC 1738 encoded consumer

secret (does not change)
L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
Bearer Token credentialsxvz1evFS4wEEPTGEFPHBog:L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
Base64 encoded Bearer Token credentials:: eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJnNmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
2단계: 앱 전용 액세스 토큰(베어러 토큰) 받기 1단계에서 계산한 값은 POST oauth2/token으로 요청을 보내 앱 전용 액세스 토큰으로 교환해야 합니다:
  • 요청은 HTTP POST 요청이어야 합니다.
  • 요청에는 Authorization 헤더가 포함되어야 하며, 값은 Basic <base64 encoded value from step 1>. 이어야 합니다.
  • 요청에는 Content-Type 헤더가 포함되어야 하며, 값은 application/x-www-form-urlencoded;charset=UTF-8. 이어야 합니다.
  • 요청 본문은 grant_type=client_credentials이어야 합니다.
요청 예시(Authorization 헤더는 줄바꿈 처리됨):
POST /oauth2/token HTTP/1.1
Host: api.x.com
User-Agent: My X App v1.0.23
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
                     NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip

grant\_type=client\_credentials
요청이 올바르게 형식화되었다면 서버는 JSON으로 인코딩된 페이로드로 응답합니다: 응답 예시:
HTTP/1.1 200 OK
상태: 200 OK
Content-Type: application/json; charset=utf-8
...
Content-Encoding: gzip
Content-Length: 140

{"token\_type":"bearer","access\_token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
애플리케이션은 반환된 객체의 token_type 키에 해당하는 값이 bearer인지 확인해야 합니다. access_token 키에 해당하는 값은 앱 전용 액세스 토큰(베어러 토큰)입니다. 앱 전용 액세스 토큰은 한 시점에 하나의 애플리케이션에만 유효합니다. 동일한 자격 증명으로 /oauth2/token에 다시 요청하면 토큰이 무효화될 때까지 동일한 토큰이 반환됩니다. 3단계: 앱 전용 액세스 토큰(베어러 토큰)으로 API 요청 인증하기 앱 전용 액세스 토큰(베어러 토큰)은 애플리케이션 전용 인증을 지원하는 API 엔드포인트에 요청을 보내는 데 사용할 수 있습니다. 앱 액세스 토큰을 사용하려면 일반적인 HTTPS 요청을 구성하고, Authorization 헤더에 Bearer <base64 bearer token value from step 2>. Signing is not required. 값을 포함하세요. 예시 요청(Authorization 헤더는 가독성을 위해 줄바꿈됨):
GET /1.1/statuses/user\_timeline.json?count=100&screen\_name=twitterapi HTTP/1.1
Host: api.x.com
User-Agent: 내 X 앱 v1.0.23
Authorization: Bearer AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAA
                      AAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Accept-Encoding: gzip
앱 전용 액세스 토큰(베어러 토큰) 무효화 앱 전용 액세스 토큰이 유출되었거나 어떤 이유로든 무효화해야 하는 경우 POST oauth2/invalidate_token 엔드포인트를 호출하세요. 요청 예시(Authorization 헤더는 줄바꿈 처리됨):
POST /oauth2/invalidate_token HTTP/1.1
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
                     NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
User-Agent: My X App v1.0.23
Host: api.x.com
Accept: */*
Content-Length: 119
Content-Type: application/x-www-form-urlencoded

access_token=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
응답 예시:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 127
...

{"access_token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}

일반적인 오류 사례

이 섹션에서는 베어러 토큰의 발급 협상 및 사용과 관련해 자주 발생하는 실수를 설명합니다. 여기에는 가능한 모든 오류 응답이 포함되어 있지 않으므로, 처리되지 않은 오류 코드와 응답에 유의하세요. 앱 전용 액세스 토큰을 발급받거나 취소하는 잘못된 요청 다음과 같은 시도:
  • 잘못된 요청으로 앱 전용 액세스 토큰(베어러 토큰)을 발급받음(예: grant_type=client_credentials를 누락).
  • 올바르지 않거나 만료된 앱 자격 증명으로 앱 전용 액세스 토큰(베어러 토큰)을 발급받거나 취소함.
  • 올바르지 않거나 이미 취소된 앱 전용 액세스 토큰(베어러 토큰)을 무효화함.
  • 짧은 시간 내에 앱 전용 액세스 토큰(베어러 토큰)을 과도하게 발급받음.
발생 결과:
HTTP/1.1 403 Forbidden
Content-Length: 105
Content-Type: application/json; charset=utf-8
...

{"errors":[{"code":99,"label":"authenticity_token_error","message":"자격 증명을 확인할 수 없습니다"}]}

API 요청에 유효하지 않은 앱 전용 액세스 토큰(베어러 토큰)이 포함됨

잘못되었거나 취소된 액세스 토큰을 사용해 API 요청을 보내면 다음과 같은 결과가 발생합니다:
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Content-Length: 61
...

{"errors":\[{"message":"유효하지 않거나 만료된 토큰","code":89}\]}

애플리케이션 전용 인증을 지원하지 않는 엔드포인트에서 앱 전용 액세스 토큰(베어러 토큰) 사용

사용자 컨텍스트가 필요한 엔드포인트(예: statuses/home_timeline)에 앱 전용 액세스 토큰(베어러 토큰)으로 요청하면 다음과 같은 결과가 발생합니다:
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Content-Length: 91
...

{"errors":\[{"message":"해당 자격 증명으로는 이 리소스에 액세스할 수 없습니다","code":220}\]}