> 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
> - Версия 4 экспериментальная: 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="Это руководство предполагает, что вы уже создали приложение OAuth2">
  Если нет, обратитесь к [этому](/oauth-2-applications/building-an-oauth-2-app) руководству и вернитесь сюда, как только получите `access_token` и `refresh_token` после авторизации через OAuth 2.
</Warning>


## Основы обновления токенов

Если вы включили область доступа ***offline*** в свой запрос учетных данных OAuth2.0, успешная аутентификация через приложение Accounts от Frame.io вернет полезную нагрузку, которая выглядит следующим образом:

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

`access_token` — это токен Bearer, который можно использовать для действий от имени аутентифицированного пользователя; он истечет через 3600 секунд (один час); после этого `refresh_token` можно использовать для получения нового `access_token`. Срок действия токена обновления истечет через 30 дней, после чего пользователю необходимо будет войти в систему заново, создав новую пару токенов доступа/обновления и т. д. Если вы явным образом не запросите область доступа *офлайн*, вы не получите `refresh_token`, и поэтому через час вам придется полностью повторно аутентифицировать пользователя.

### Получение токена обновления при выполнении аутентификации

Вы не можете использовать `refresh_token`, которого у вас нет, поэтому обязательно в своем приложении:
* Запросите область доступа **офлайн**.
* Получите `refresh_token`, который возвращается в выполненном обратном вызове.

Для удобства обратный вызов из наших [руководств по приложениям OAuth 2](/oauth-2-applications/building-an-oauth-2-app) воспроизведен здесь, включая вызов `os` для сохранения токена обновления. Обратите внимание, что предоставлено два примера: один с настроенным PKCE (не включает заголовок базовой аутентификации) и один без него (включает заголовок базовой аутентификации).

### Без PKCE




**`Python`**

```python title="Python"
def callback():
  # Where `request` refers to our initial call to the auth URL
  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. 
  response = requests.post(TOKEN, auth=client_auth, data=post_data)    
	# Stash the refresh token for later
  os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]

  return response.text
```





### С PKCE




**`Python`**

```python title="Python"
def callback():
  # Where `request` refers to our initial call to the auth URL
  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 using PKCE, use the below request with no auth
  response = requests.post(TOKEN_URL, data=post_data)
  # Stash the refresh token for later
  os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]

  return response.text
```




## Выполнение обновления




Само обновление — это один вызов URL токена Frame.io:



* Метод: POST
* URL: **https://applications.frame.io/oauth2/token**
* `Тип контента`: *application/x-www-form-urlencoded*




Обновление всегда будет включать как минимум следующие три атрибута в данных формы:



* `grant_type`: *refresh_token*
* `scope`: &lt;scopes&gt;
* `refresh_token`: &lt;refresh_token&gt;

Если вы используете PKCE, нужно будет включить `client_id` вашего приложения в эти данные формы; если нет, нужно будет включить заголовок базовой аутентификации с `client_id` и `client_secret` вашего приложения в качестве имени пользователя и пароля соответственно.

### Без PKCE

Аналогично [выполнению первоначального обратного вызова аутентификации](/oauth-2-applications/building-an-oauth-2-app#the-callback) без PKCE, это стандартное обновление потребует предоставления ваших `client_id` и `client_secret` в качестве имени пользователя и пароля в заголовке базовой аутентификации.

**`Python`**

```python title="Python"
def refresh():
  # Fetch the refresh token, assuming we have it
  REFRESH_TOKEN = os.environ.get('REFRESH_TOKEN')

  client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID,CLIENT_SECRET)
  post_data = {
    "grant_type": "refresh_token",
    "scope": SCOPE,
    "refresh_token": REFRESH_TOKEN
    # if using PKCE, you will need to include your client_id as below
    # "client_id": CLIENT_ID 
  }

  response = requests.post(TOKEN_URL, auth=client_auth, data=post_data)
  # Catch + stash a new Refresh Token
  os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]

  return response.text
```




### С PKCE

И снова мы следуем правилам нашего первоначального цикла `/callback`:
* Мы не включаем заголовок `Авторизация`
* Мы должны включить `client_id` в наши полезные данные




**`Python`**

```python title="Python"
def refresh():
  # Fetch the refresh token, assuming we have it
  REFRESH_TOKEN = os.environ.get('REFRESH_TOKEN')

  post_data = {
    "grant_type": "refresh_token",
    "scope": SCOPE,
    "refresh_token": REFRESH_TOKEN
    "client_id": CLIENT_ID 
  }

  response = requests.post(TOKEN_URL, data=post_data)
  # Catch + stash a new Refresh Token
  os.environ['REFRESH_TOKEN'] = response.json()["refresh_token"]

  return response.text
```




Поздравляем!Теперь вы можете управлять полным жизненным циклом токенов клиентского приложения OAuth2.0.