---
title: トークンの保管と有効期限
description: アクセストークンとリフレッシュトークンの有効期限、更新のしかた、安全な保管方法です。
---

外部連携APIのトークンは、店舗のメンバーが許可したことの証明です。漏れると、その店舗の情報を第三者に読まれます。次の決まりを守ってください。

## 有効期限

| トークン             | 有効期限     | 使い方                                                       |
| -------------------- | ------------ | ------------------------------------------------------------ |
| アクセストークン     | 発行から15分 | APIを呼ぶときに `Authorization: Bearer` で付けます           |
| リフレッシュトークン | 発行から90日 | アクセストークンの期限が切れたら、新しいトークンと交換します |

リフレッシュトークンは、使うたびに新しいものに入れ替わります。交換に使った古いリフレッシュトークンは、それ以後使えません。定期的に更新していれば、90日を過ぎても接続を続けられます。

## 更新のしかた

```ts
const response = await fetch(
  "https://api.toreca-cloud.com/api/auth/oauth2/token",
  {
    method: "POST",
    headers: {
      Authorization: "Basic " + basicCredentials,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      grant_type: "refresh_token",
      refresh_token: storedRefreshToken,
      resource: "https://api.toreca-cloud.com/partner/v1",
    }),
  },
);
const next = await response.json();
// next.refresh_token を保存し直す（古いものは使えなくなる）
```

- APIが `401` を返したら、リフレッシュトークンで更新してから1回だけ再試行します。
- 更新は1つの接続につき同時に1回にしてください。並行して更新すると、片方が古いリフレッシュトークンを使って失敗します。
- 新しいリフレッシュトークンは、受け取ったらすぐに保存します。保存に失敗すると、次の更新ができなくなります。
- 更新が `invalid_grant` で失敗したら、店舗のメンバーにもう一度許可してもらいます。

## 保管のしかた

- トークンとクライアントシークレットは、サーバー側だけに置きます。ブラウザ、スマホアプリ、静的サイトのJavaScriptには入れないでください。
- データベースに保存するときは暗号化し、読める人と処理を絞ります。
- ログ、エラー報告、分析ツールにトークンを出さないでください。
- クライアントシークレットが漏れたおそれがあるときは、店舗の管理者に「シークレットを再発行」を頼みます。古いシークレットはすぐに使えなくなります。

## 接続が止まるとき

次のときは、トークンが期限内でもAPIが拒否されます。

| 状況                                                 | 応答                     |
| ---------------------------------------------------- | ------------------------ |
| 店舗が接続を解除した                                 | `403 connection_revoked` |
| 店舗または運営がアプリを停止した                     | `403 client_disabled`    |
| 許可したメンバーが退会した、または必要な権限を失った | `403 forbidden`          |
| 必要な権限（scope）がトークンにない                  | `403 insufficient_scope` |

外部アプリから接続をやめるときは `DELETE /partner/v1/connection` を呼びます。このアプリがその店舗で持つリフレッシュトークンもすべて失効します。
