セッションベースとトークンベースの認証を理解する


こんにちは、Gaji-Labo フロントエンドエンジニアの上條です。
今回は、自分の学習のために認証・認可について調べてみた結果をまとめてみたいと思います。
学習前の知識レベルとしては、認証・認可というワードは聞いたことあるけど違いがあやふやで自信を持って説明できないくらいでした。というのも実務でのログイン周りの実装はチーム内の得意な人にお願いしており、自分で実装するとしても個人開発などで Firebase のようなライブラリに頼った実装で留まっていたため、認証・認可という本質的なところには届いてなかったように思います。

認証・認可とは

どちらもログイン周りの実装には欠かせない知識ですが、言葉が似ていて混乱します。ざっくり説明すると以下のようになります。

認証(Authentication):相手が誰かを確認する
認可(Authorization):リソースにアクセスできる権限があるか確認する

よくある例え話ですが、世の中のサービスには Google のようなユーザー情報を持ったアカウントでログインできるものがありますよね(身近なものだと Figma、miro、Notion あたりが思い浮かびます)。それらのアカウントでサービスにログインする場合、まずは自身の Google アカウントに ID/パスワードでログイン(認証)し、認証が完了した後に「このサービスがアクセスを求めています。アクセスを許可しますか?」のような確認画面が表示されると思います。許可すれば Google アカウントに対してそのサービスへのアクセスを許可した=認可したことになります。

なんとなく認証・認可についてイメージが湧くでしょうか。以降は主な認証方法について解説したいと思います。

認証方法

認証方法でよく名前を見るのは以下の4つですが、実務でよく使われるのは後者の2つです。

  • Basic 認証
  • ダイジェスト認証
  • セッションベースの認証
  • トークンベースの認証

Basic 認証はデメリットとしてID/パスワードを暗号化せず通信するため盗聴すればログイン情報が分かってしまう点、通信する度にログイン情報を送る点が挙げられます。ID/パスワードをハッシュ化し解析を困難にしたものがダイジェスト認証なのですが、通信する度にログイン情報を送る点は Basic 認証と変わらずデメリットとして存在します。これらの理由から Basic 認証・ダイジェスト認証は実務ではあまり使用されない印象です。

毎回ログイン情報を送る点を解決するのがセッションベースの認証です。認証が完了したらサーバーはクライアントにランダムなセッションIDを付与し、クライアントは与えられたセッションIDを Cookie などに保存した状態で通信します。セッションIDが一致していれば本人とみなされるため、ログイン情報を通信に含めなくてよくなります。

一方トークンベースの認証はセッションIDではなく改ざんが難しいアクセストークン(一般的に JWT)を使用します。認証が完了したらサーバーはクライアントにアクセストークンを付与し、クライアントは与えられたアクセストークンを Cookie などに保存した状態で通信します。サーバーは送られてきたアクセストークンが改ざんされていないか、有効期限が切れていないかなどを検証します。

セッションベースとトークンベースの違い

ここまでだとログイン情報がセッションIDかアクセストークンに代わるだけで両者の違いが分かりづらいですが、大きな違いが2点挙げられます。

認証のための情報をサーバーに保存する必要があるか

セッション:ある
認証が完了したタイミングでユーザー情報とセッションIDを紐づける情報を保存します。サーバーに情報を持つためステートフルであると言われます。

トークン:ない
トークンのみで検証するため保存する必要はなく、ステートレスであると言われます。

②セッションID・アクセストークンが無効化されるか

セッション:される
ログアウトしたり一定期間非アクディブだった場合はセッションが終了され、セッションIDも無効化されます。その際に①のサーバーに保存した認証のための情報も破棄されます。

トークン:されない
ログアウトしたタイミングでブラウザに保存していたアクセストークンは破棄されますが、発行されたアクセストークンそのものは削除されません。そのためアクセストークンが流出すると第三者がアクセスできてしまいうため、アクセストークンの有効期限を短く設定することやトークン削除の実装がベストプラクティスとして推奨されています。
JSON Web Token (JWT) のベストプラクティス | Auth0 by Okta

まとめ

はじめに書いた通りの知識レベルに加え、JWT はなんとなく知っている・Basic 認証は個人で使ったことあるなど断片的な知識は持っていましたが、今回学んだこととそれらが繋がったような感覚を持ちました。具体的な実装方法はこれから学んでいくつもりなので、その過程でも引き続き理解を深めていけるといいなと思っています。

参考

今さら聞けない認証方法まとめ #Security – Qiita
ウェブサイトのさまざまな「認証方式」をまとめて比較した結果がコレ – GIGAZINE
よくわかる認証と認可 | DevelopersIO
セッションベース認証とトークンベース認証の違いを分かりやすくまとめてみる | zenn

Gaji-Labo フロントエンドエンジニア向けご案内資料

Gaji-Labo は Next.js 開発の実績と知見があります

フロントエンド開発の専門家である私たちが御社の開発チームに入ることで、バックエンドも含めた全体の開発効率が上がります。

「既存のサイトを Next.js に移行したい」
「人手が足りず信頼できるエンジニアを探している」
「自分たちで手を付けてみたがいまいち上手くいかない」

フロントエンド開発に関わるお困りごとがあれば、まずは一度お気軽に Gaji-Labo にご相談ください。

オンラインでのヒアリングとフルリモートでのプロセス支援にも対応しています。

フロントエンドの相談をする!

投稿者 Kamijo Momoka

フロントエンドエンジニア。
HTML/CSS/JavaScript/WordPressでのサイト制作からNext.js/TypeScriptなどを使ったWebアプリ開発、FigmaでのUIデザインまで広く経験しています。 デザインエンジニアと名乗るのが夢です。