> This page is for プラットフォーム, version レガシー.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://developer.frame.io/platform/v4/llms.txt
> - V4 Experimental: https://developer.frame.io/platform/v4-experimental/llms.txt
> - レガシー: https://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://developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://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
```

## コールバック
次に、承認サーバーは `GET` リクエストを `REDIRECT_URI` に対して実行し、今度はこれが `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` をリクエストできるようになりました。