0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

access_tokenとrefresh_tokenの違い

Last updated at Posted at 2025-02-24

はじめに

JWT認証におけるaccess_tokenとrefresh_tokenの使い分けを見ながら、両者の違いを説明します。

説明しないこと
JWTはログイン機能でよく利用されます。
詳しいログイン機能の作成方法については解説しません。

JWTとは

JWTは(Json Web Token)の略で、JSON形式のデータに情報を格納したものをtoken化したものです。Webアプリケーションの認証(JWT認証)によく使われます。

JWTの仕組み

JWTはヘッダ.ペイロード.署名の3つに分けられ、.で区切られます。

# jwtの例
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3NDAyOTQ5MTd9.feyNR9Itzv-58R0U3TFFUCD5yTcn_z3ucClFCKJkyg8

ペイロード部分にユーザーidなどを格納して、認証が必要な通信でheadersのAuthorizationに含めて送信します。payload部分は誰でも簡単に複合化することが可能なので、password等の機密情報を入れたりしてはいけません。 悪意のあるユーザーがpayloadを書き換えても、署名部分が合わなくなるので、改ざんを検知することが可能です。

access_tokenとrefresh_token

access_tokenとrefresh_tokenは使用されるタイミングが異なります。

tokenの構造等に違いがあるわけではありません。
JWTを使った認証方式の場合、access_tokenもrefresh_tokenもJWTです。
tokenを2つ使う理由はセキュリティの向上です。

※ refresh_tokenはuuidなどランダムな文字列を使用する場合もあります。JWTである必要はありません

2つのtokenを使用する理由

APIでやり取りをするアプリケーションの場合、リクエストの度にaccess_token(JWT)をサーバーに送信する必要があります。
つまりネットワーク上にaccess_tokenが流れる回数が増え、当然盗聴されるリスクも高まります。単純に盗聴する機会が増えるからです。

有効期限が1ヶ月のtokenが悪意のあるユーザに盗聴された場合、1ヶ月もの間不正ログインされる状態になります。頻繁にネットワーク上でやり取りされるaccess_tokenは有効期限を短く設定するのが望ましいです。

しかし、access_token単体の運用だと、頻繁にログインし直す必要があるため、ユーザー体験が悪くなります。

そこでrefresh tokenの登場です。

有効期限の考え方

例えば、refresh tokenの有効期限を1ヶ月。access_tokenの有効期限を1時間に設定します。

access_tokenの有効期限が切れた状態でアプリケーションを訪れた場合に、refresh_tokenを使用してaccess_tokenの再発行を行います。 以降のリクエストでは、access_tokenを利用して通信します。
再度access_tokenが切れた際にrefresh_tokenで再発行。 これを繰り返します。

これで、毎回の通信では有効期限の短いaccess_tokenを利用することでセキュリティリスクを下げ、access_tokenの有効期限が切れた時だけ、resresh_tokenによる再取得を実行することで、ユーザの利便性も確保することができます。

ユーザーが再度ログインする必要があるのはrefresh_tokenの有効期限が切れる1ヶ月後です。

refresh_tokenの保存と検証ステップ

JWT(access_token)を使用したAPI通信では、JWTをサーバ側で保持しませんが、refresh_tokenはDBに保存します。
refresh_tokenを使用した再検証時には、以下2つのステップでaccess_tokenの再発行を行います。

1 該当のrefresh_tokenを保持するユーザデータはあるか
2 refresh_tokenの有効期限は切れていないか

refresh_tokenをDBに保持しておくと、万が一refresh_tokenが流出した可能性のあるユーザが発生した場合に、該当のユーザーに紐づくrefresh_tokenのDBから削除することで、流出したrefresh_tokenの有効期限が残っていても無効化させることが可能です。

仮のaccess_tokenだけの運用をしていた場合、secret_keyを変更する必要が出てきます。 その場合全てのユーザのaccess_tokenが無効になります。

※ refresh_tokenは漏洩リスクを考えハッシュ化するのが望ましいです

refresh_tokenの取り扱い

access_tokenはJSONの戻り値として返したり、response headerとして返し、localStorageやRedux等の状態管理ライブラリで保存されます。

一方でrefresh_tokenはセキュアに管理するため、HTTPOnly Cookieで管理されます。
HTTPOnly CookieはJavaScriptからのアクセスできないCookieです。 XSSによる攻撃から守ることができます。

クロスドメイン(HTTPOnly Cookie)

注意点として、クロスドメイン環境の場合、safariはデフォルトでサードパーティ製Cookieをブロックします。
つまりsafariユーザーはrefresh_tokenを利用できないので、最後にAPI通信を行ってから1時間経つと毎回ログインする必要があります。
これを回避するにはrefresh_tokenもaccess_tokenと同じようにJSONやresponse headersでやりとりし、Content Security Policy (CSP)を厳密にするなどして、可能な限りのXSS対策を行うなど、別の手が必要です。

結論

refresh_tokenはaccess_tokenの再取得のために使われる。
access_token: 頻繁にネットワークに晒されるため、有効期限設定して漏洩した時のリスクを抑える
refresh_token: 有効期限を長めに設定するが、ネットワークに晒される回数は少ないため漏洩する危険性は少ない

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?