- 교차 출처 리소스 공유
- 지원되는 OAuth 2.0 흐름
access token
으로 GitLab API에 접근하기- HTTPS로 Git에 액세스하기
access token
- 토큰 정보 검색
- 토큰 취소
- OAuth 2.0 토큰과 GitLab 레지스트리
OAuth 2.0 아이덴티티 프로바이더 API
GitLab은 OAuth 2.0 프로토콜을 통해 사용자를 대신하여 GitLab 리소스에 접근할 수 있도록 서드 파티 서비스에 API를 제공합니다.
이를 위해 GitLab을 구성하려면
GitLab을 OAuth 2.0 인증 아이덴티티 프로바이더로 설정하기를 참조하세요.
이 기능은 doorkeeper Ruby gem을 기반으로 합니다.
교차 출처 리소스 공유
- CORS 사전 요청 지원은 GitLab 15.1에서 도입되었습니다.
많은 /oauth
엔드포인트는 교차 출처 리소스 공유(CORS)를 지원합니다. GitLab 15.1부터는 다음 엔드포인트도 지원합니다:
CORS 사전 요청:
/oauth/revoke
/oauth/token
/oauth/userinfo
사전 요청에는 특정 헤더만 사용할 수 있습니다:
- 간단한 요청에 대한 헤더.
-
Authorization
헤더.
예를 들어, X-Requested-With
헤더는 사전 요청에 사용할 수 없습니다.
지원되는 OAuth 2.0 흐름
GitLab은 다음과 같은 인증 흐름을 지원합니다:
-
코드 교환을 위한 증명 키(Proof Key for Code Exchange, PKCE) 사용한 인증 코드:
가장 안전한 흐름입니다. PKCE가 없으면 모바일 클라이언트에서 클라이언트 비밀을 포함해야 하며, 클라이언트 및 서버 앱 모두에서 추천됩니다. -
인증 코드:
안전하고 일반적인 흐름입니다. 안전한 서버 측 앱에 권장되는 옵션입니다. -
리소스 소유자 비밀번호 자격 증명:
오직 안전하게 호스팅되는 1차 서비스에만 사용해야 합니다. GitLab은 이 흐름의 사용을 권장하지 않습니다. -
디바이스 인증 부여(GitLab 17.1 이상):
브라우저 접근이 없는 장치에 맞춰진 안전한 흐름입니다. 인증 흐름을 완료하려면 보조 장치가 필요합니다.
OAuth 2.1의 초안 사양은 암시적 부여 및 리소스 소유자 비밀번호 자격 증명 흐름을 명시적으로 제외합니다.
모든 흐름이 작동하는 방법과 귀하의 사용 사례에 적합한 흐름을 선택하려면
OAuth RFC를 참조하세요.
인증 코드(PKCE가 있거나 없는)의 흐름은 /user_settings/applications
페이지를 통해 먼저 application
이 등록되어야 합니다.
등록 중에 적절한 범위를 활성화하여 application
이 접근할 수 있는 리소스의 범위를 제한할 수 있습니다. 생성 후에는
application
자격 증명인: Application ID 및 _Client Secret_을 받게 됩니다. _Client Secret_은 안전하게 보관해야 합니다.
또한 애플리케이션 아키텍처가 허용하는 경우 _Application ID_를 비밀로 유지하는 것이 유리합니다.
GitLab의 범위 목록은 공급자 문서를 참조하세요.
CSRF 공격 방지
리디렉션 기반 흐름을 보호하기 위해,
OAuth 사양은 요청 시마다 /oauth/authorize
엔드포인트에 대해 사용자 에이전트에 안전하게 바인딩된 “상태 매개변수에 포함된 일회용 CSRF 토큰”의 사용을 권장합니다.
이것은 CSRF 공격을 방지할 수 있습니다.
프로덕션에서 HTTPS 사용
프로덕션에서는 redirect_uri
에 HTTPS를 사용하세요.
개발의 경우, GitLab은 안전하지 않은 HTTP 리디렉션 URI를 허용합니다.
OAuth 2.0이 보안을 전적으로 전송 계층에 기반하고 있기 때문에, 보호되지 않은
URI를 사용해서는 안 됩니다. 자세한 내용은 OAuth 2.0 RFC와 OAuth 2.0 위협 모델 RFC를 참조하세요.
다음 섹션에서는 각 흐름에 따라 인증을 얻는 방법에 대한 자세한 지침을 찾을 수 있습니다.
인증 코드와 함께 코드 교환을 위한 증명 키 (PKCE)
PKCE RFC에는 인증 요청부터 접근
토큰까지의 자세한 흐름 설명이 포함되어 있습니다. 다음 단계에서는 이 흐름의 구현을 설명합니다.
인증 코드와 함께하는 PKCE 흐름, 줄여서 PKCE는, 사용자로부터 비밀을
보호할 수 없는 공개 클라이언트에서 클라이언트 자격 증명의 OAuth 교환을
안전하게 수행할 수 있게 합니다. 이것은 비밀을 사용자가 볼 수 없도록
하는 것이 기술적으로 불가능한 단일 페이지 JavaScript 애플리케이션이나 기타
클라이언트 측 앱에 유리합니다.
흐름을 시작하기 전에 STATE
, CODE_VERIFIER
및 CODE_CHALLENGE
를 생성하세요.
-
STATE
는 클라이언트가 요청과 콜백 간의 상태를 유지하는 데 사용되는 예측할 수 없는 값입니다. CSRF 토큰으로도 사용해야 합니다. -
CODE_VERIFIER
는 길이가 43에서 128자 사이의 무작위 문자열로,A-Z
,a-z
,0-9
,-
,.
,_
,~
문자를 사용합니다. -
CODE_CHALLENGE
는CODE_VERIFIER
의 SHA256 해시를 URL 안전하게
base64로 인코딩한 문자열입니다:- SHA256 해시는 인코딩하기 전에 이진 형식이어야 합니다.
- Ruby에서는
Base64.urlsafe_encode64(Digest::SHA256.digest(CODE_VERIFIER), padding: false)
로 설정할 수 있습니다. - 참고로,
CODE_VERIFIER
문자열ks02i3jdikdo2k0dkfodf3m39rjfjsdk0wk349rj3jrhf
를 해시하고
위의 Ruby 코드를 사용하여 인코딩하면CODE_CHALLENGE
문자열
2i0WFA-0AerkjQm4X4oDEhqA17QIAKNjXpagHBXmO_U
가 생성됩니다.
-
인증 코드 요청. 이를 위해, 사용자를 다음 쿼리 매개 변수가 포함된
/oauth/authorize
페이지로 리디렉션해야 합니다:https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=STATE&scope=REQUESTED_SCOPES&code_challenge=CODE_CHALLENGE&code_challenge_method=S256
이 페이지는 사용자에게
REQUESTED_SCOPES
에 지정된 범위를 기반으로
앱이 자신의 계정에 접근할 수 있도록 요청을 승인하도록 요청합니다.
사용자는 이후 지정된REDIRECT_URI
로 리디렉션됩니다. scope 매개 변수는
사용자와 관련된 범위의 공백으로 구분된 목록입니다.
예를 들어,scope=read_user+profile
은read_user
및profile
범위를 요청합니다.
리디렉션에는 인증code
가 포함되며, 예를 들면 다음과 같습니다:https://example.com/oauth/redirect?code=1234567890&state=STATE
-
이전 요청에서 반환된 인증
code
(다음 예제에서RETURNED_CODE
로 표시됨)를 사용하여
HTTP 클라이언트를 통해access_token
을 요청할 수 있습니다. 다음 예제는 Ruby의rest-client
를 사용합니다:parameters = 'client_id=APP_ID&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI&code_verifier=CODE_VERIFIER' RestClient.post 'https://gitlab.example.com/oauth/token', parameters
예 응답:
{ "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", "token_type": "bearer", "expires_in": 7200, "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1", "created_at": 1607635748 }
-
새로운
access_token
을 가져오기 위해refresh_token
매개 변수를 사용하세요.
Refresh token은access_token
자체가 만료된 후에도 사용할 수 있습니다.
이 요청은:- 기존의
access_token
및refresh_token
을 무효화합니다. - 응답으로 새로운 토큰을 보냅니다.
parameters = 'client_id=APP_ID&refresh_token=REFRESH_TOKEN&grant_type=refresh_token&redirect_uri=REDIRECT_URI&code_verifier=CODE_VERIFIER' RestClient.post 'https://gitlab.example.com/oauth/token', parameters
예 응답:
{ "access_token": "c97d1fe52119f38c7f67f0a14db68d60caa35ddc86fd12401718b649dcfa9c68", "token_type": "bearer", "expires_in": 7200, "refresh_token": "803c1fd487fec35562c205dac93e9d8e08f9d3652a24079d704df3039df1158f", "created_at": 1628711391 }
- 기존의
참고:
redirect_uri
는 원래 인증 요청에 사용된 redirect_uri
와 일치해야 합니다.
이제 접근 토큰을 사용하여 API에 요청할 수 있습니다.
인증 코드 흐름
자세한 흐름 설명을 참조하세요.
인증 코드 흐름은 본질적으로
PKCE를 사용하는 인증 코드 흐름과 동일합니다.
흐름을 시작하기 전에 STATE
를 생성하세요. 이는 요청과 콜백 간의 상태를 유지하기 위해 클라이언트가 사용하는 예측할 수 없는 값입니다. 또한 CSRF 토큰으로 사용해야 합니다.
-
인증 코드를 요청합니다. 이를 위해 사용자를 다음 쿼리 매개변수로
/oauth/authorize
페이지로 리디렉션해야 합니다:https://gitlab.example.com/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code&state=STATE&scope=REQUESTED_SCOPES
이 페이지는 사용자에게
REQUESTED_SCOPES
에 명시된 범위에 따라 앱이 계정에 접근하는 요청을 승인하도록 요청합니다. 사용자는 지정된REDIRECT_URI
로 다시 리디렉션됩니다.
scope 매개변수은 사용자가 승인한 범위의 공백으로 구분된 목록입니다.
예를 들어,scope=read_user+profile
은read_user
및profile
범위를 요청합니다.
리디렉션에는 인증code
가 포함됩니다. 예를 들면:https://example.com/oauth/redirect?code=1234567890&state=STATE
-
이전 요청에서 반환된 인증
code
(다음 예제에서RETURNED_CODE
로 표시된)를 사용하여
어떠한 HTTP 클라이언트를 사용하여access_token
을 요청할 수 있습니다.
다음 예제는 Ruby의rest-client
를 사용합니다:parameters = 'client_id=APP_ID&client_secret=APP_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI' RestClient.post 'https://gitlab.example.com/oauth/token', parameters
예제 응답:
{ "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", "token_type": "bearer", "expires_in": 7200, "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1", "created_at": 1607635748 }
-
새
access_token
을 가져오려면refresh_token
매개변수를 사용하세요.
access_token
이 만료된 후에도 refresh token을 사용할 수 있습니다. 이 요청은:- 기존의
access_token
과refresh_token
을 무효화합니다. - 응답에 새 토큰을 전송합니다.
parameters = 'client_id=APP_ID&client_secret=APP_SECRET&refresh_token=REFRESH_TOKEN&grant_type=refresh_token&redirect_uri=REDIRECT_URI' RestClient.post 'https://gitlab.example.com/oauth/token', parameters
예제 응답:
{ "access_token": "c97d1fe52119f38c7f67f0a14db68d60caa35ddc86fd12401718b649dcfa9c68", "token_type": "bearer", "expires_in": 7200, "refresh_token": "803c1fd487fec35562c205dac93e9d8e08f9d3652a24079d704df3039df1158f", "created_at": 1628711391 }
- 기존의
redirect_uri
는 원래 인증 요청에서 사용된 redirect_uri
와 일치해야 합니다.이제 반환된 액세스 토큰과 함께 API 요청을 할 수 있습니다.
디바이스 인증 승인 흐름
- 도입됨 GitLab 17.2 플래그
oauth2_device_grant_flow
와 함께.- 기본적으로 활성화됨 17.3에서.
플래그:
이 기능의 사용 가능성은 기능 플래그에 의해 제어됩니다.
자세한 내용은 기록을 참조하세요.
참고:
RFC 사양에서 디바이스 인증 승인 흐름에 대한 상세한 설명을 확인하세요. 브라우저 로그인에서 토큰 응답까지의 과정이 포함됩니다.
디바이스 인증 승인 흐름은 브라우저 상호작용이 불가능한 입력 제한 장치에서 GitLab 신원을 안전하게 인증할 수 있게 해줍니다.
따라서 디바이스 인증 승인 흐름은 헤드리스 서버 또는 UI가 없거나 제한된 다른 장치에서 GitLab 서비스를 사용하려는 사용자에게 이상적입니다.
-
디바이스 인증을 요청하기 위해, 입력 제한 장치 클라이언트에서
https://gitlab.example.com/oauth/authorize_device
로 요청이 전송됩니다. 예를 들어:parameters = 'client_id=UID&scope=read' RestClient.post 'https://gitlab.example.com/oauth/authorize_device', parameters
성공적인 요청 후,
verification_uri
가 포함된 응답이 사용자에게 반환됩니다. 예를 들어:{ "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS", "user_code": "0A44L90H", "verification_uri": "https://gitlab.example.com/oauth/device", "verification_uri_complete": "https://gitlab.example.com/oauth/device?user_code=0A44L90H", "expires_in": 300, "interval": 5 }
- 디바이스 클라이언트는 요청한 사용자에게 응답의
user_code
와verification_uri
를 표시합니다. 해당 사용자는 그런 다음 브라우저 접근이 가능한 보조 장치에서:- 제공된 URI로 이동합니다.
- 사용자 코드를 입력합니다.
- 프롬프트에 따라 인증을 완료합니다.
-
verification_uri
와user_code
를 표시한 직후, 디바이스 클라이언트는 초기 응답에서 반환된 관련device_code
로 토큰 엔드포인트를 폴링하기 시작합니다:parameters = 'grant_type=urn:ietf:params:oauth:grant-type:device_code &device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS &client_id=1406020730' RestClient.post 'https://gitlab.example.com/oauth/token', parameters
- 디바이스 클라이언트는 토큰 엔드포인트로부터 응답을 수신합니다. 인증이 성공적이었다면, 성공 응답이 반환되고, 그렇지 않으면 오류 응답이 반환됩니다.
잠재적인 오류 응답은 다음 두 가지로 분류됩니다:- OAuth 인증 프레임워크 액세스 토큰 오류 응답에서 정의된 오류.
- 여기에서 설명하는 디바이스 인증 승인 흐름에 특정한 오류.
디바이스 흐름에 특정한 오류 응답은 다음 콘텐츠에 설명되어 있습니다.
각 잠재적 응답에 대한 자세한 내용은 관련 디바이스 인증 승인에 대한 RFC 사양과 인증 토큰에 대한 RFC 사양을 참조하세요.예제 응답:
{ "error": "authorization_pending", "error_description": "..." }
이 응답을 수신하면, 디바이스 클라이언트는 계속해서 폴링을 진행합니다.
폴링 간격이 너무 짧으면, 느린 속도의 오류 응답이 반환됩니다. 예를 들면:
{ "error": "slow_down", "error_description": "..." }
이 응답을 수신하면, 디바이스 클라이언트는 폴링 속도를 줄이고 새로운 속도로 계속 폴링합니다.
디바이스 코드가 인증 완료 전에 만료되면, 만료된 토큰 오류 응답이 반환됩니다. 예를 들어:
{ "error": "expired_token", "error_description": "..." }
그 시점에서 디바이스 클라이언트는 중지하고 새로운 디바이스 인증 요청을 시작해야 합니다.
인증 요청이 거부되면, 접근 거부 오류 응답이 반환됩니다. 예를 들어:
{ "error": "access_denied", "error_description": "..." }
인증 요청이 거부되었습니다. 사용자는 자격 증명을 확인하거나 시스템 관리자에게 문의해야 합니다.
-
사용자가 성공적으로 인증되면, 성공 응답이 반환됩니다:
{ "access_token": "TOKEN", "token_type": "Bearer", "expires_in": 7200, "scope": "read", "created_at": 1593096829 }
이 시점에서 디바이스 인증 흐름이 완료됩니다. 반환된 access_token
은 GitLab 리소스에 접근할 때 사용자 신원을 인증하는 데 제공될 수 있습니다. 예를 들어, HTTPS를 통해 클론하거나 API에 접근할 때 사용할 수 있습니다.
클라이언트 측 디바이스 흐름을 구현하는 샘플 애플리케이션은 다음에서 찾을 수 있습니다: https://gitlab.com/johnwparent/git-auth-over-https.
리소스 소유자 비밀번호 자격 증명 흐름
상세 흐름 설명을 참조하세요.
이 흐름에서, 리소스 소유자 자격 증명(사용자 이름 및 비밀번호)에 대한 교환으로 토큰이 요청됩니다.
자격 증명은 다음과 같은 경우에만 사용해야 합니다:
- 리소스 소유자와 클라이언트 간에 신뢰도가 높을 경우. 예를 들어, 클라이언트가 기기 운영 체제의 일부이거나 매우 특권이 있는 애플리케이션인 경우입니다.
- 다른 인증 부여 유형을 사용할 수 없는 경우(예: 인증 코드 등).
신뢰할 수 있는 환경에 클라이언트가 배포될 때만 이 인증 부여 유형을 사용하십시오.
99%의 경우
개인 액세스 토큰이 더 나은 선택입니다.
이 인증 부여 유형은 클라이언트가 리소스 소유자 자격 증명에 직접 접근해야 하지만,
리소스 소유자 자격 증명은 단일 요청에만 사용되며 액세스 토큰으로 교환됩니다.
이 인증 부여 유형은 리소스 소유자 자격 증명을 미래에 사용할 필요 없이
장기간 사용 가능한 액세스 토큰 또는 새로 고침 토큰과 교환함으로써
클라이언트가 자격 증명을 저장할 필요성을 제거할 수 있습니다.
액세스 토큰을 요청하려면, 다음 매개변수와 함께 /oauth/token
에 POST 요청을 해야 합니다:
{
"grant_type" : "password",
"username" : "user@example.com",
"password" : "secret"
}
예시 cURL 요청:
echo 'grant_type=password&username=<your_username>&password=<your_password>' > auth.txt
curl --data "@auth.txt" --request POST "https://gitlab.example.com/oauth/token"
등록된 OAuth 애플리케이션과 함께 이 인증 부여 흐름을 사용할 수도 있습니다.
애플리케이션의 client_id
와 client_secret
을 사용한 HTTP 기본 인증을 사용하여:
echo 'grant_type=password&username=<your_username>&password=<your_password>' > auth.txt
curl --data "@auth.txt" --user client_id:client_secret \
--request POST "https://gitlab.example.com/oauth/token"
그런 다음, 액세스 토큰을 포함하는 응답을 받게 됩니다:
{
"access_token": "1f0af717251950dbd4d73154fdf0a474a5c5119adad999683f5b450c460726aa",
"token_type": "bearer",
"expires_in": 7200
}
기본적으로, 액세스 토큰의 범위는 api
로 설정되어 있어 전체 읽기/쓰기 접근을 제공합니다.
테스트를 위해 oauth2
Ruby gem을 사용할 수 있습니다:
client = OAuth2::Client.new('the_client_id', 'the_client_secret', :site => "https://example.com")
access_token = client.password.get_token('user@example.com', 'secret')
puts access_token.token
access token
으로 GitLab API에 접근하기
access token
을 사용하면 사용자를 대신하여 API에 요청을 보낼 수 있습니다.
토큰을 GET 매개변수로 전달할 수 있습니다:
GET https://gitlab.example.com/api/v4/user?access_token=OAUTH-TOKEN
또는 토큰을 Authorization 헤더에 넣을 수도 있습니다:
curl --header "Authorization: Bearer OAUTH-TOKEN" "https://gitlab.example.com/api/v4/user"
HTTPS로 Git에 액세스하기 access token
read_repository
또는 write_repository
범위를 가진 토큰은 HTTPS를 통해 Git에 액세스할 수 있습니다. 암호로 토큰을 사용하세요.
사용자 이름을 임의의 문자열로 설정할 수 있습니다. oauth2
를 사용해야 합니다:
https://oauth2:<your_access_token>@gitlab.example.com/project_path/project_name.git
또는 Git 자격 증명 헬퍼를 사용하여 OAuth로 GitLab에 인증할 수 있습니다. 이는 OAuth 토큰 갱신을 자동으로 처리합니다.
토큰 정보 검색
토큰의 세부 정보를 확인하려면 Doorkeeper gem에서 제공하는 token/info
엔드포인트를 사용하세요. 자세한 내용은 /oauth/token/info
를 참조하세요.
액세스 토큰을 다음과 같이 제공해야 합니다:
-
매개변수로:
GET https://gitlab.example.com/oauth/token/info?access_token=<OAUTH-TOKEN>
-
Authorization 헤더에:
curl --header "Authorization: Bearer <OAUTH-TOKEN>" "https://gitlab.example.com/oauth/token/info"
다음은 응답 예입니다:
{
"resource_owner_id": 1,
"scope": ["api"],
"expires_in": null,
"application": {"uid": "1cb242f495280beb4291e64bee2a17f330902e499882fe8e1e2aa875519cab33"},
"created_at": 1575890427
}
사용 중지된 필드
scopes
와 expires_in_seconds
필드는 응답에 포함되지만 이제 사용되지 않습니다. scopes
필드는 scope
의 별칭이며, expires_in_seconds
필드는 expires_in
의 별칭입니다. 자세한 내용은 Doorkeeper API 변경 사항을 참조하세요.
토큰 취소
토큰을 취소하려면 revoke
엔드포인트를 사용하세요. API는 성공을 나타내기 위해 200 응답 코드와 빈 JSON 해시를 반환합니다.
parameters = 'client_id=APP_ID&client_secret=APP_SECRET&token=TOKEN'
RestClient.post 'https://gitlab.example.com/oauth/revoke', parameters
OAuth 2.0 토큰과 GitLab 레지스트리
표준 OAuth 2.0 토큰은 GitLab 레지스트리에 대한 다양한 접근 수준을 지원합니다. 이들은:
- 사용자가 다음에 인증할 수 없도록 허용합니다:
- GitLab 컨테이너 레지스트리.
- GitLab 패키지 레지스트리에 나열된 패키지.
- 사용자가 컨테이너 레지스트리 API를 통해 레지스트리를 가져오고, 나열하고, 삭제할 수 있도록 허용합니다.