Open Cloud는 클라이언트가 기밀인지 공개인지에 따라 PKCE 여부에 따라 OAuth 2.0 인증 흐름을 지원합니다.
- 기밀 클라이언트는 백엔드에서 보안으로 저장하고 검색할 수 있는 비밀을 저장하고 검색할 수 있는 웹사이트와 같이 자격 증명을 기밀로 유지할 수 있는 앱입니다.
- 공용 클라이언트는 모바일 및 웹 브라우저 앱과 같이 비밀을 유지할 수 없는 앱입니다.
모든 클라이언트에 대해 OAuth 2.0 인증 코드 흐름을 PKCE로 사용하고 공용 클라이언트에 대해 요구하며 모든 클라이언트에 대해 이를 요구합니다.
승인 코드 흐름을 구현하기 위해 앱은 다음 단계를 수행합니다:
- 코드 확인기 및 코드 챌린지 생성(PKCE만).이렇게 하면 클라이언트 비밀이 아닌 요청에 도전을 포함할 수 있으므로 보안이 향상됩니다.
- 적절한 매개변수로 권한 끝점에 GET 요청을 보내십시오.
- 승인 콜백을 처리합니다.승인을 받은 후, 앱 작품중에 지정한 URL로 리디렉션 요청에서 Roblox의 승인 코드를 사용하십시오.나중에 사용할 권한 코드를 분석합니다.
- 토큰 끝점에 권한 코드로 POST 요청을 보내십시오.성공하면 API 호출을 수행할 액세스 및 새로 고침 토큰을 받습니다.
- 액세스하려는 리소스에 대한 참조 문서에 따라 OAuth 2.0 인증을 지원하는 모든 오픈 클라우드 API를 호출합니다.
다음 섹션에서는 각 단계를 더 자세히 설명합니다.
코드 챌린지 생성(PKCE만)
승인 프로세스를 시작하기 전에 코드 검사기에서 코드 챌린지를 생성해야 합니다.선택한 프로그래밍 언어의 라이브러리나 기본 함수를 사용하여 코드 검사기를 만들고, 해시를 계산하고, Base64 인코딩을 수행하여 코드 도전을 생성할 수 있습니다.
코드 검사기를 생성할 때 대/소문자(A-Z, a-z), 10진수(0-9), 하이픈(-), 마침표(.), 밑줄(_), 그리고 밑줄(-)의 최소 길이는 43자이고 최대 길이는 128자인 경우에만 예약되지 않은 문자만 사용하십시오.
다음 예제에서는 Javascript를 사용하여 코드 확인기를 만들고 SHA-256 해시 알고리즘을 사용하여 코드 도전을 생성하는 방법을 보여줍니다:
Generate Code Challenge
const crypto = require('crypto');
// base64URL encode the verifier and challenge
function base64URLEncode(str) {
return str.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// create sha256 hash from code verifier
function sha256(buffer) {
return crypto.createHash('sha256').update(buffer).digest(`base64`);
}
// create a random code verifier
var code_verifier = base64URLEncode(crypto.randomBytes(32));
// generate a challenge from the code verifier
var code_challenge = base64URLEncode(sha256(code_verifier));
PKCE의 경우 코드 검사기와 후속 단계에서 도전 값이 모두 필요합니다.
승인 URL 생성
사용자 권한 부여 프로세스를 시작하려면 필요한 매개변수로 인증 URL을 생성하십시오:
- : 앱 등록 후 얻은 앱의 클라이언트 ID.
- redirect_uri : 앱의 리디렉션 URI, 앱의 재입장 지점.
- scope : 공간 구분 목록에서 앱이 필요로 하는 액세스 권한을 정의하는 요청된 범위.
- response_type : 권한 코드 흐름을 나타내기 위해 설정을 code 로 변경합니다. PKCE에만 필요합니다
- code_challenge : 코드 검사기에서 생성된 코드 챌린지.
- code_challenge_method : 코드 챌린지가 SHA-256 알고리즘을 사용하여 변환되었음을 나타내기 위해 이 매개변수 값을 S256 로 설정하여 가장 널리 지원되고 안전한 코드 챌린지 방법을 사용했습니다.
- state : 요청과 콜백 사이의 상태를 유지하기 위한 불투명하고 안전한 랜덤 값. PKCE가 아닌 경우에만 필요합니다
- : 앱 등록 후 얻은 앱의 클라이언트 비밀.PKCE로 인증을 사용하는 경우 이 매개변수를 생략합니다.권한 요청 URL은 다음 예제와 같이 잘 포맷되어야 합니다:
PKCE 권한 URL 예시
https://apis.roblox.com/oauth/v1/authorize?client_id=7290610391231237934964&code_challenge=PLEKKVCjdD1V_07wOKlAm7P02NC-LZ_1hQfdu5XSXEI&code_challenge_method=S256&redirect_uri=https://example.com/redirect&scope=openid%20profile&response_type=code&state=abc123
사용자가 URL을 방문하면 권한 흐름을 통해 이동됩니다. 성공하면 Roblox가 사용자를 지정된 redirect_uri로 리디렉션합니다.
권한 승인 콜백 처리 Handle authorization callbacks
승인 흐름이 성공하면 앱은 지정한 에서 Roblox 승인 서버에 요청을 받습니다.요청에서 당신은 code(승인 코드)와 state(이전에 값을 제공한 경우) 매개변수를 받습니다.
code 매개 변수에는 앱이 권한 서버에서 액세스 토큰으로 교환할 수 있는 인증 코드가 포함되어 있습니다.대부분의 백엔드 서버 언어에는 쿼리 매개변수를 디코딩된 개체로 액세스하는 표준 방법이 있습니다.액세스 토큰을 교환하기 위해 code 매개 변수를 가져와야 하고 이를 사용해야 합니다.
state 매개 변수는 권한 요청에 처음 제공한 불투명한 값입니다.이 매개변수를 사용하여 승인 프로세스의 상태나 컨텍스트를 유지할 수 있습니다.
예를 들어, 리디렉션 URI를 https://example.com/redirect로 지정하면 다음 URL로 GET 요청을 받을 수 있습니다.
예제 리디렉션 URL
https://example.com/redirect?code=10c45PNuquKnFJ6pUcy5-fHkghEM6lSegm-7hj9mVEprub1dSDuStuKK_EAUXY7AHTD63xcnmvxSLthp-C8g3jzIGZVzuXSd20Y2dEYI9hx0LZmPg95ME4z2K03UheiZbroyXUjYyB3ReoMqobzDVPzyx6IS8kj2Uu-11Xq_0JiTYxtDatuqXRNIAmJT8gMJmbSyOLOP_vnDvbeMUiBsqCRrkTGVbWSwYSc8sTVVE-535kYdqQOgNjH1ffCoZLGl8YYxLnpb2CXJlRQPrcjkA&state=6789
권한이 실패하면 앱은 GET , error , error_description 및 state (해당하는 경우) 매개 변수로 지정된 리디렉션 URL에 요청을 받습니다.
- error 매개 변수는 승인 프로세스 중에 발생한 특정 OAuth 2.0 오류를 나타냅니다.
- error_description 매개 변수는 오류의 추가 세부 정보를 제공합니다.
- state 매개 변수는 앱이 오류 발생 시 상태를 유지하도록 도와줍니다.
액세스 토큰에 대한 권한 코드 교환 Exchange an authorization code for access tokens
권한을 분석했을 때 code , 원하는 Roblox 리소스에 액세스하기 위해 토큰으로 교환합니다.
액세스 토큰과 새로 고침 토큰을 요청하려면 POST에 요청을 보내 합니다.요청에는 권한 코드, 클라이언트 ID 및 코드 검사 값(PKCE) 또는 클라이언트 비밀(PKCE가 아님)이 x-www-form-urlencoded 형식으로 포함되어야 합니다.
받은 응답에서 적용 가능한 토큰을 분석합니다.액세스 토큰은 15분 동안 유효합니다.일반적으로 서버 측에서 새로 고침 토큰을 안전하게 저장하여 나중에 새 토큰을 얻을 수 있습니다.
예제 토큰 끝점 응답{"access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IlBOeHhpb2JFNE8zbGhQUUlUZG9QQ3FCTE81amh3aXZFS1pHOWhfTGJNOWMiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwiYWlkIjoiM2Q2MWU3NDctM2ExNS00NTE4LWJiNDEtMWU3M2VhNDUyZWIwIiwic2NvcGUiOiJvcGVuaWQ6cmVhZCBwcm9maWxlOnJlYWQiLCJqdGkiOiJBVC5QbmFWVHpJU3k2YkI5TG5QYnZpTCIsIm5iZiI6MTY5MTYzOTY5OCwiZXhwIjoxNjkxNjQwNTk4LCJpYXQiOjE2OTE2Mzk2OTgsImlzcyI6Imh0dHBzOi8vYXBpcy5yb2Jsb3guY29tL29hdXRoLyIsImF1ZCI6IjcyOTA2MTAzOTc5ODc5MzQ5Nj1234.BjwMkC8Q5a_iP1Q5Th8FrS7ntioAollv_zW9mprF1ats9CD2axCvupZydVzYphzQ8TawunnYXp0Xe8k0t8ithg","refresh_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoidGpHd1BHaURDWkprZEZkREg1dFZ5emVzRWQyQ0o1NDgtUi1Ya1J1TTBBRSIsInR5cCI6IkpXVCJ9..nKYZvjvXH6msDG8Udluuuw.PwP-_HJIjrgYdY-gMR0Q3cabNwIbmItcMEQHx5r7qStVVa5l4CbrKwJvjY-w9xZ9VFb6P70WmXndNifnio5BPZmivW5QkJgv5_sxLoCwsqB1bmEkz2nFF4ANLzQLCQMvQwgXHPMfCK-lclpVEwnHk4kemrCFOvfuH4qJ1V0Q0j0WjsSU026M67zMaFrrhSKwQh-SzhmXejhKJOjhNfY9hAmeS-LsLLdszAq_JyN7fIvZl1fWDnER_CeDAbQDj5K5ECNOHAQ3RemQ2dADVlc07VEt2KpSqUlHlq3rcaIcNRHCue4GfbCc1lZwQsALbM1aSIzF68klXs1Cj_ZmXxOSOyHxwmbQCHwY7aa16f3VEJzCYa6m0m5U_oHy84iQzsC-_JvBaeFCachrLWmFY818S-nH5fCIORdYgc4s7Fj5HdULnnVwiKeQLKSaYsfneHtqwOc_ux2QYv6Cv6Xn04tkB2TEsuZ7dFwPI-Hw2O30vCzLTcZ-Fl08ER0J0hhq4ep7B641IOnPpMZ1m0gpJJRPbHX_ooqHol9zHZ0gcLKMdYy1wUgsmn_nK_THK3m0RmENXNtepyLw_tSd5vqqIWZ5NFglKSqVnbomEkxneEJRgoFhBGMZiR-3FXMaVryUjq-N.Q_t4NGxTUSMsLVEppkTu0Q6rwt2rKJfFGuvy3s12345","token_type": "Bearer","expires_in": 899,"id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IkNWWDU1Mi1zeWh4Y1VGdW5vNktScmtReFB1eW15YTRQVllodWdsd3hnNzgiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwibmFtZSI6ImxpbmtzZ29hdCIsIm5pY2tuYW1lIjoibGlua3Nnb2F0IiwicHJlZmVycmVkX3VzZXJuYW1lIjoibGlua3Nnb2F0IiwiY3JlYXRlZF9hdCI6MTYwNzM1NDIzMiwicHJvZmlsZSI6Imh0dHBzOi8vd3d3LnJvYmxveC5jb20vdXNlcnMvMjA2NzI0Mzk1OS9wcm9maWxlIiwibm9uY2UiOiIxMjM0NSIsImp0aSI6IklELnltd3ZjTUdpOVg4azkyNm9qd1I5IiwibmJmIjoxNjkxNjM5Njk4LCJleHAiOjE2OTE2NzU2OTgsImlhdCI6MTY5MTYzOTY5OCwiaXNzIjoiaHR0cHM6Ly9hcGlzLnJvYmxveC5jb20vb2F1dGgvIiwiYXVkIjoiNzI5MDYxMDM5Nzk4NzkzNDk2NCJ9.kZgCMJQGsariwCi8HqsUadUBMM8ZOmf_IPDoWyQY9gVX4Kx3PubDz-Q6MvZ9eU5spNFz0-PEH-G2WSvq2ljDyg","scope": "openid profile"}
리소스 메서드에 전화 걸기
이제 필요한 액세스 토큰을 가지고 있으므로 리소스 메서드에 인증된 호출을 하도록 사용할 수 있습니다.액세스 토큰을 모든 API 요청의 헤더에 포함하여 승인하세요.
예를 들어, 전체 승인 흐름을 통과하여 앱이 올바르게 작동하는지 테스트한 다음 액세스 토큰으로 사용자 정보 끝점에 요청을 보내 앱을 테스트할 수 있습니다.이 끝점을 호출하기 전에 openid 또는 openid 및 profile 범위 모두를 가지고 있는지 확인하십시오.성공하면 해당 끝점의 응답은 다음과 같습니다:
사용자 정보 응답 예시
{
"sub": "12345678",
"name": "Jane Doe",
"nickname": "robloxjanedoe",
"preferred_username": "robloxjanedoe",
"created_at": 1607354232,
"profile": "https://www.roblox.com/users/12345678/profile"
}