アプリケーション開発におけるSession Token — 概要、動作原理、JWTとの違い

著者: IT Sectr 公開日: 2026-04-05 読了時間: 9 分

Session Tokenは、ユーザー認証成功後にサーバーが作成し、後続のリクエストを識別するために使用する一意の識別子です。自己完結型トークン(JWT)とは異なり、session tokenはランダムな文字列であり、それ自体にはデータが含まれていません。すべてのセッション情報はサーバーのRAMまたはデータベースに保存されます。OAuth.com(2025年)によると、session tokenはサーバーサイドのWebアプリケーションとハイブリッドモバイルアーキテクチャで最も一般的な認証メカニズムであり続けています。

重要なポイント

  • Session Token — サーバーサイドのセッションデータを参照するランダムな識別子
  • Stateful — サーバーはRedis、Memcached、またはデータベースにセッション状態を保存する
  • 簡単な失効 — サーバー上のセッションレコードを削除するだけでトークンが無効になる
  • セキュリティ — データはトークンに保存されないため、デコードによる漏洩が防止される
  • Cookie — HttpOnly、Secure、SameSiteフラグを使用したWebアプリケーションでのsession tokenの伝統的な転送方法

Session Tokenとは

Session Token(セッション識別子)は、ユーザー認証後にサーバーが生成し、セッションデータに関連付ける一意の文字列です。トークンにはユーザー情報は含まれません — これは単にサーバーに保存されたデータへのキーです。このアプローチはstateful認証と呼ばれます。サーバーは各アクティブセッションの状態を保存し、すべてのリクエストでそれを検証します。

セッションデータには以下が含まれます:ユーザーID、ログイン時間、IPアドレス、user-agent、権限リスト、最終アクティビティ時間。クライアントがsession tokenを含むリクエストを送信すると、サーバーはセッションストア内の対応するレコードを見つけ、その有効性を確認し、リクエスト処理のためにデータを取得します。セッションレコードが存在しないか期限切れの場合、サーバーは認証エラーを返し、再ログインを要求します。

OWASP(2025年)によると、session tokenは即時のアクセス失効が必要なアプリケーションの標準であり続けています — たとえば、銀行システムや企業ポータルでは、管理者がユーザーセッションを即座に終了できる必要があります。このようなシステムでは、session tokenは追加のブロックメカニズムなしではstatelessトークンでは達成できない完全なアクセス制御を提供します。

Session Tokenの仕組み

プロセスは、クライアントが認証サーバーに資格情報を送信することから始まります。サーバーはログインとパスワードを検証し、ストア(通常はRedisまたはデータベース)にセッションレコードを作成し、クライアントに一意のsession tokenを返します。クライアントはトークンを保存し、後続のリクエストごとにそれを送信し、サーバーは毎回セッションの存在と有効性を確認します。

サーバーセッションとストレージ

Redisは、インメモリストレージとTTL(生存時間)サポートのおかげで最も人気のあるセッションストアです。各セッションはキーと値のペアとして保存され、キーはsession token、値はセッションデータを含むJSONオブジェクトです。TTLは期限切れのセッションを自動的に削除します。代替手段:Memcached(メモリのみ、ディスク永続化なし)、PostgreSQL/MySQL(永続的だが低速)、およびDynamoDB(AWSインフラストラクチャ用)。

Redisでのセッション構造の例:session:{token}{“userId”: 42, “role”: “admin”, “createdAt”: 1812345678, “lastAccess”: 1812345678}。サーバーは各リクエストでlastAccessを更新し、非アクティブタイムアウトを実装できます — 非アクティブ期間後の自動セッション終了です。

Cookie vs ヘッダー

Session Tokenは、HTTP CookieまたはAuthorization HTTPヘッダーの2つの方法で送信できます。CookieはWebアプリケーションの伝統的な方法です。サーバーはHttpOnly(JavaScriptからアクセス不可)、Secure(HTTPSのみ)、SameSite(CSRF保護)フラグを付けてCookieを設定します。モバイルアプリケーションでは、ネイティブクライアントでCookieメカニズムが常に便利とは限らないため、Authorization: Bearer <session_token>ヘッダーがより一般的に使用されます。

Session Tokenのライフサイクル

Session Tokenのライフサイクルは、作成、アクティブセッションの維持、終了の3つの段階で構成されます。各段階で、トークンの漏洩や傍受を防ぐための適切なセキュリティ設定が必要です。

作成、保存、削除

作成 — サーバーは128〜256ビットの暗号的に安全なランダム文字列を生成します(たとえば、JavaのSecureRandomやPythonのos.urandomを使用)。トークンは予測不可能である必要があります — エントロピーなしでのUUIDやタイムスタンプの使用は許容されません。保存はクライアント側で:iOSではKeychain、AndroidではEncryptedSharedPreferences、WebではHttpOnly Cookie。削除はログアウト時に発生します。クライアントはストアからトークンを削除し、サーバーはRedisからセッションレコードを削除します。ログアウト後、session tokenは無価値になります — サーバーは対応するレコードを見つけられません。

SANS Institute(2025年)によると、適切なセッション終了の実装(サーバーサイドのクリーンアップを伴うログアウト)は、盗まれたトークンを使用した攻撃の最大70%を防ぎます。クライアント側でトークンを削除するだけでなく、サーバー側でセッションを無効にすることも重要です。

Session Token vs JWT

Session TokenとJWTは、2つの異なる認証アプローチを表しています。Session Tokenはstateful(サーバーが状態を保存)、JWTはstateless(データはトークン内)です。どちらを選択するかは、アプリケーションのアーキテクチャとセキュリティ要件によって異なります。

基準Session TokenJWT
モデルStateful(データはサーバー上)Stateless(データはトークン内)
失効即時 — Redisからセッションを削除ブラックリストまたは短いTTLが必要
サイズ16〜64バイト500〜2000バイト
データ保存サーバーのみ(安全)トークン内(base64、暗号化なし)
スケーリング共有ストレージ(Redis)が必要不要 — トークンはローカルで検証
CSRF保護SameSite Cookie + CSRFトークンが必要不要(トークンはヘッダー内)

Session Tokenを選ぶべき場合

Session Tokenは以下の場合に適しています:即時のセッション失効が必要な場合(銀行、管理パネル)、アプリケーションが共有Redisを使用する1台または複数のサーバーで動作する場合、セッションデータが大きくJWTに収まらない場合、またはチームがトークンデコードによるデータ漏洩のリスクを最小化したい場合。このようなシナリオでは、session tokenは疑わしいアクティビティがあった場合に即座にアクセスをブロックします — Redisから1つのレコードを削除するだけで、ユーザーのすべてのセッションが無効になります。

Redis(2025年)によると、セッションキーレベルでのTTL(EXPIREコマンド)の使用は、バックグラウンドタスクにオーバーヘッドをかけることなく、期限切れセッションを自動的にクリアします。TTLが1時間で10,000の同時ユーザー負荷があるセッションの場合、Redisは1KBのセッションサイズで約1GBのRAMを消費し、ほとんどのアプリケーションにとってコスト効率が良くなります。

Session Tokenのセキュリティ

Session Tokenのセキュリティは、2つの原則に基づいています:トークンは予測不可能でなければならず、転送と保存の際に保護されなければなりません。主な脅威は、トークンの傍受(man-in-the-middle、XSS)、予測(弱い生成)、およびセッションフィクセーション(session fixation)です。

トークン盗難からの保護

保護には以下が含まれます:トークンを含むすべてのリクエストにHTTPSを使用、短いセッションTTL(15〜60分の非アクティブ)の設定、IPとuser-agentへのセッションのバインド(各リクエストでの追加検証)、CookieへのSecureおよびHttpOnlyフラグの使用、および機密操作(パスワード変更、権限昇格)後の定期的なsession tokenのローテーション。OWASPはまた、ログイン後に新しいセッションを作成する際に古いセッションを無効にするセッション管理の実装を推奨しています — これによりセッションフィクセーションが防止されます。

OWASP ASVS(2025年)によると、セッションは少なくとも2つの要素にバインドされる必要があります:トークン自体(クライアントが持つもの)とIP/user-agent(サーバーが知っているもの)。これらの要素が一致しない場合、サーバーはセッションを終了し、再認証を要求する必要があります。

Kotlinでの実装例

以下は、Spring BootとRedisを使用したKotlinでのサーバーサイドsession token実装の例です。サーバーはSecureRandomを介して暗号的に安全なトークンを生成し、TTL付きでRedisにセッションを保存し、各リクエストで検証します。コードは3つの主要な操作を示しています:セッション作成、検証、および無効化。

kotlin
data class Session(
    val userId: Long,
    val role: String,
    val createdAt: Long,
    val lastAccess: Long
)

object SessionManager {
    private val redis = JedisPool("localhost", 6379)

    fun createSession(userId: Long, role: String): String {
        val token = generateSecureToken()
        val session = Session(userId, role, now(), now())
        redis.resource.use { conn ->
            conn.setex("session:$token", 3600, toJson(session))
        }
        return token
    }

    fun validateSession(token: String): Session? {
        redis.resource.use { conn ->
            val json = conn.get("session:$token") ?: return null
            return fromJson(json)
        }
    }

    fun invalidateSession(token: String) {
        redis.resource.use { it.del("session:$token") }
    }

    private fun generateSecureToken(): String {
        val bytes = ByteArray(32)
        SecureRandom().nextBytes(bytes)
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)
    }
}

この実装では、Redisへのスレッドセーフな接続にJedisPoolを使用しています。createSessionメソッドは1時間(3600秒)のTTLを設定します — この期間後、Redisは自動的にレコードを削除します。validateSessionメソッドは、存在しないか期限切れのセッションに対してnullを返し、サーバーが無効なトークンを持つリクエストを正しく処理してHTTP 401を返せるようにします。

よくある質問

Session tokenとaccess tokenの違いは何ですか?

Session tokenはサーバーサイドのセッション識別子(stateful)です。Access tokenはAPIアクセスのための資格情報(JWTまたはopaque)です。Session tokenは通常Webセッションに使用され、access tokenはモバイルおよびSPAアプリケーションでのAPIリクエストに使用されます。両者は共存できます:Web用のsession token、API用のaccess token。

XSS攻撃からsession tokenを保護するには?

主な保護は、セッショントークンを含むCookieにHttpOnlyフラグを設定することです。このフラグはJavaScriptからのCookieアクセスを防ぎ、XSS攻撃によるトークン盗難を無効にします。さらに、SameSite=StrictフラグはクロスサイトリクエストでのCookie送信を防ぎ、CSRFから保護します。

Session tokenの有効期間はどのくらいにすべきですか?

2つのタイムアウトが推奨されます:絶対タイムアウト(8〜24時間 — 最大セッション寿命)と相対タイムアウト(15〜30分の非アクティブ — その後セッション終了)。銀行アプリケーションの場合、絶対タイムアウトは1〜2時間に短縮されます。メールクライアントの場合は7日間に達することがあります。

セッションフィクセーションとは何ですか?

Session fixationは、攻撃者がユーザーに既知のセッション識別子を使用させる攻撃です。保護:認証成功後、サーバーはクライアントから送信されたトークンを継続して使用するのではなく、新しいsession tokenを作成する必要があります。古いトークンはその起源に関係なく無効化される必要があります。

REST APIでsession tokenを使用できますか?

はい、クライアントがAuthorizationヘッダー(Cookieではなく)で送信する場合、session tokenはREST APIに適しています。モバイルアプリケーションでは、これが一般的な方法です。欠点:複数のサーバーにスケーリングする場合、共有セッションストア(Redis)が必要になり、アーキテクチャに単一障害点が追加されます。

まとめ

  • Session Token — サーバーサイドのセッションデータを参照するstateful識別子
  • 利点 — 即時失効とサーバー上のセッションの完全制御
  • ストレージ — 自動クリーンアップのためのTTL付きRedis、Memcached、またはデータベース
  • セキュリティ — SecureRandom生成、HTTPS、HttpOnly + SameSite Cookie
  • Session vs JWT — Sessionは失効が容易、JWTはスケーリングが容易
  • タイムアウト — 絶対(8〜24時間)および相対(15〜30分の非アクティブ)
  • セッションフィクセーション — ログイン後に新しいトークンを作成して防止

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください