> This page is for 플랫폼, version 레거시.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 실험적: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - 레거시: https://next.developer.frame.io/platform/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# OAuth 2 앱 구축

<Warning title="이 가이드에서는 이미 OAuth 2 앱을 등록했다고 가정합니다">
  등록하지 않은 경우 [OAuth 2 코드 흐름](/oauth-2-applications/oauth-2-code-authorization-flow)을 참조하여 애플리케이션을 구성하세요.
</Warning>


## 애플리케이션 기본 사항

**참고**: `client_id` 및(PKCE를 사용하지 않는 경우) `client_secret`을 안전하게 저장하고 환경을 통해 액세스해야 합니다. 아래 예시에서는 `CLIENT_ID` 및 `CLIENT_SECRET` 변수를 포함하는 **.env** 파일이 있다고 가정합니다.

**`Python`**

```python title="Python"
import urllib, requests, requests.auth
import os

CLIENT_ID = os.environ.get('CLIENT_ID')
CLIENT_SECRET = os.environ.get('CLIENT_SECRET')

AUTHORIZE_URL = "https://applications.frame.io/oauth2/auth"
TOKEN_URL = "https://applications.frame.io/oauth2/token"
# The scopes you've chosen for your app, space-delimited
SCOPE = "offline account.read asset.read" 
# The callback URI for your app
REDIRECT_URI = "https://yourapp.domain/callback"
```





## 인증 서버 호출




먼저 애플리케이션에서 Frame.io 인증 서버를 호출해야 합니다. 그러면 사용자가 로그인 페이지로 리디렉션됩니다.





**`Python`**

```python title="Python"
import uuid
from urllib.parse import urlencode

def create_auth_url():
 credentials = {
  'response_type': 'code',
  'redirect_uri': REDIRECT_URI,
  'client_id': CLIENT_ID,
  'scope': SCOPE,
  'state': str(uuid.uuid4())
 }
 url = (AUTHORIZE_URL + "?" + urlencode(credentials))
 return url
```





## 콜백

그런 다음 인증 서버가 `REDIRECT_URI`에 `GET` 요청을 수행하며, 차례로 `TOKEN_URL`을 호출해야 합니다. 이 콜백은 애플리케이션이 PKCE를 사용하도록 구성되었는지 여부에 따라 약간 다릅니다.

### PKCE 미사용

PKCE를 사용하지 않는 경우 콜백에 `CLIENT_ID` 및 `CLIENT_SECRET`을 포함하는 `Authorization` 헤더가 포함되어야 합니다.

**`Python`**

```python title="Python"
def callback():
   state = request.args.get('state')
   scope = request.args.get('scope')
   code = request.args.get('code')
   error = request.args.get('error')

   if error:
     return "Error: " + error

   # Set up for client authorization and set up the data you need to send.
   client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)

   post_data = {
     "grant_type": "authorization_code",
     "code": code,
     "redirect_uri": REDIRECT_URI,
     "state": state,
     "scope": SCOPE
   }

# Send a POST request with the data you need to receive an access token. 
# If everything goes well, it will be returned to you and you can use it with
# Frame.io.

   response = requests.post(TOKEN_URL, auth=client_auth, data=post_data)    
   return response.text
```





### PKCE 사용

PKCE를 사용하는 경우 콜백에 `Authorization` 헤더가 포함되지 *않아야* 하지만, `TOKEN_URL`로 다시 호출할 때 `POST` 요청 본문에 `CLIENT_ID`가 *반드시* 포함되어야 합니다.

**`Python`**

```python title="Python"
def callback():
   state = request.args.get('state')
   scope = request.args.get('scope')
   code = request.args.get('code')
   error = request.args.get('error')

   if error:
     return "Error: " + error

# If using PKCE, you must include the CLIENT_ID in your request body  
   post_data = {
     "grant_type": "authorization_code",
     "code": code,
     "redirect_uri": REDIRECT_URI,
     "state": state,
     "scope": SCOPE
     "client_id": CLIENT_ID 
   }

# Send a POST request with the data you need to receive an access token. 
# If everything goes well, it will be returned to you and you can use it with
# Frame.io

  # If using PKCE, use the below request with no auth
  response = requests.post(TOKEN_URL, data=post_data) 

   return response.text
```





## 성공적인 응답




콜백에 성공하면 다음과 같은 JSON 응답을 받게 됩니다.




```json
{
  "access_token":"BEARER_TOKEN",
  "expires_in":3600,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"account.read offline",
  "token_type":"bearer"
}
```

이제 `access_token`을 사용하여 로그인한 사용자를 대신해 Frame.io에 API 호출을 수행할 수 있으며, 이 토큰이 만료된 후 `refresh_token`을 사용하여 새 `access_token`을 요청할 수 있습니다.