OAuth 2 トークンの更新

このガイドは、OAuth 2 アプリが構築済みであることを前提としています

まだの場合は、こちらのガイドを参照してください。OAuth 2 資格情報の付与が成功して access_tokenrefresh_token を取得したら、ここに戻ってきてください。

トークン更新の基本

OAuth2.0 資格情報リクエストにオフラインスコープを含めた場合、Frame.io の Accounts アプリケーションを介した認証に成功すると、次のようなペイロードが返されます。 ******

1{
2 "access_token":"BEARER_TOKEN",
3 "expires_in":3600,
4 "refresh_token":"REFRESH_TOKEN",
5 "scope":"account.read offline",
6 "token_type":"bearer"
7}

access_token は、認証されたユーザーの代理で動作するために使用できるベアラートークンであり、3600 秒(1 時間)後に期限切れになります。その後、refresh_token を使用して新しい access_token を取得できます。更新トークンは 30 日後に期限切れになります。その時点で、ユーザーに一からログインしてもらうことが必要になり、新しいアクセス/更新トークンペアなどが生成されます。

オフラインスコープを明示的にリクエストしなかった場合は、refresh_token **を受け取らないので、1 時間後にユーザーを完全に再認証する必要があります。

認証に成功したときの更新トークンのキャプチャ

言うまでもなく、持っていない refresh_token を使用することはできません。アプリで次のようにしてください。

  • オフラインスコープをリクエストする
  • 正常なコールバックで返された refresh_token をキャプチャする

便宜上、OAuth 2 アプリガイドからのコールバックがここに再現されており、os 更新トークンを隠す呼び出しがあります。次の 2 つの例が提供されていることに注意してください。1 つは PKCE が設定されている例(基本認証ヘッダーを含まない)、もう 1 つは設定されていない例(基本認証ヘッダーを含む)。

PKCE なし

Python
1def callback():
2 # Where `request` refers to our initial call to the auth URL
3 state = request.args.get('state')
4 scope = request.args.get('scope')
5 code = request.args.get('code')
6 error = request.args.get('error')
7
8 if error:
9 return "Error: " + error
10
11 # Set up for client authorization and set up the data you need to send.
12 client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
13
14 post_data = {
15 "grant_type": "authorization_code",
16 "code": code,
17 "redirect_uri": REDIRECT_URI,
18 "state": state,
19 "scope": SCOPE
20 }
21
22 # Send a POST request with the data you need to receive an access token.
23 response = requests.post(TOKEN, auth=client_auth, data=post_data)
24 # Stash the refresh token for later
25 os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]
26
27 return response.text

PKCE を使用

Python
1def callback():
2 # Where `request` refers to our initial call to the auth URL
3 state = request.args.get('state')
4 scope = request.args.get('scope')
5 code = request.args.get('code')
6 error = request.args.get('error')
7
8 if error:
9 return "Error: " + error
10
11 # If using PKCE, you must include the CLIENT_ID in your request body
12 post_data = {
13 "grant_type": "authorization_code",
14 "code": code,
15 "redirect_uri": REDIRECT_URI,
16 "state": state,
17 "scope": SCOPE
18 "client_id": CLIENT_ID
19 }
20
21 # Send a POST request with the data you need to receive an access token.
22 # If using PKCE, use the below request with no auth
23 response = requests.post(TOKEN_URL, data=post_data)
24 # Stash the refresh token for later
25 os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]
26
27 return response.text

更新の実行

更新自体は、Frame.io のトークン URL への 1 回の呼び出しです。

更新には常に、フォームデータに少なくとも次の 3 つの属性が含まれます。

  • grant_type:refresh_token **
  • scope:<SCOPES>
  • refresh_token:<REFRESH_TOKEN>

PKCE を使用している場合は、このフォームデータにアプリの client_id を含めることが必要になります。そうでない場合は、アプリの client_id および client_secret をそれぞれユーザー名、パスワードとして含んだ基本認証ヘッダーを含めることが必要になります。

PKCE なし

PKCE なしで初期認証コールバックを行う場合と同様に、この標準更新には、基本認証ヘッダーで client_idおよび client_secret をユーザー名およびパスワードとして指定する必要があります。

Python
1def refresh():
2 # Fetch the refresh token, assuming we have it
3 REFRESH_TOKEN = os.environ.get('REFRESH_TOKEN')
4
5 client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID,CLIENT_SECRET)
6 post_data = {
7 "grant_type": "refresh_token",
8 "scope": SCOPE,
9 "refresh_token": REFRESH_TOKEN
10 # if using PKCE, you will need to include your client_id as below
11 # "client_id": CLIENT_ID
12 }
13
14 response = requests.post(TOKEN_URL, auth=client_auth, data=post_data)
15 # Catch + stash a new Refresh Token
16 os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]
17
18 return response.text

PKCE を使用

繰り返しますが、初期 /callback サイクルのルールを模倣しています。

  • Authorization ヘッダーは含めません
  • ペイロードに client_id を含める必要があります
Python
1def refresh():
2 # Fetch the refresh token, assuming we have it
3 REFRESH_TOKEN = os.environ.get('REFRESH_TOKEN')
4
5 post_data = {
6 "grant_type": "refresh_token",
7 "scope": SCOPE,
8 "refresh_token": REFRESH_TOKEN
9 "client_id": CLIENT_ID
10 }
11
12 response = requests.post(TOKEN_URL, data=post_data)
13 # Catch + stash a new Refresh Token
14 os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]
15
16 return response.text

完了しました。OAuth2.0 クライアントアプリケーションのトークンライフサイクル全体を処理できるようになりました。