Webアプリケーションにおいて、ユーザーが「誰であるか」を確認し(認証)、そのユーザーが「何ができるか」を判断する(認可)機能は、セキュリティとユーザー体験の基盤となります。この章では、これらの機能を実装するための主要なメカニズムと技術について解説します。
1. 認証(Authentication)と認可(Authorization)の違い
認証 (Authentication) ... ユーザーが主張する本人であることを確認するプロセス。(例:ログイン画面でのID/パスワードの照合)
認可 (Authorization) ... 認証されたユーザーが、特定のリソースや操作へのアクセス権を持っているか判断するプロセス。(例:管理者のみが設定変更できる、自分の投稿のみ編集できる)
2. セッションベースの認証とCookieの利用
伝統的なWebアプリケーションで広く使われてきたのが、セッションとCookieを利用した認証方式です。
A. 認証の流れ
ログイン: ユーザーがIDとパスワードを送信し、サーバーで認証処理が行われます。
セッションIDの発行: 認証が成功すると、サーバーはユーザーの認証状態を保持するためのセッションを作成し、一意のセッションIDを生成します。
Cookieの設定: サーバーは、このセッションIDをブラウザに保存させるために、Set-Cookieヘッダーを使ってセッションIDを含むCookieを返します。
リクエストのたびに送信: ユーザーのブラウザは、以降のすべてのリクエストに自動的にこのセッションID入りCookieを付加してサーバーに送信します。
セッションの確認: サーバーはリクエストからセッションIDを取得し、保存されているセッション情報と照合して、ユーザーを特定・認証します。
B. Cookieの役割と注意点
役割: クライアント側(ブラウザ)に少量の情報を保存し、次回のアクセス時にサーバーへ送信するメカニズムです。セッションベース認証では、セッションIDを保持するために利用されます。
注意点:
CSRF対策: セッションIDを盗用した不正なリクエストを防ぐため、CSRFトークンなどの対策が必須です。
HttpOnly属性: スクリプトからのアクセスを防ぎ、XSSによるセッションIDの盗難リスクを減らすために、CookieにHttpOnly属性を設定することが推奨されます。
3. トークン認証とJWT(JSON Web Token)
セッションベース認証は、サーバー側でセッション情報を管理する必要があり、特に複数のサーバーで構成される大規模な分散システムやAPIサービスには不向きです。そこで登場したのが、トークン認証です。
A. トークン認証の基本
ステートレス(Stateless): サーバーがセッション情報を保持しません。認証状態はトークン自体に格納されます。
認証の流れ: ログイン成功後、サーバーは認証情報を含むアクセストークンを生成し、クライアントに返します。クライアントは以降のリクエストのヘッダー(通常は
Authorization: Bearer <トークン>)にトークンを付加して送信します。サーバーはトークンを検証し、認証・認可を行います。
B. JWT (JSON Web Token) の詳解
JWTは、トークン認証で最も広く利用されている標準規格の一つです。認証情報やクレーム(要求)をJSON形式で格納し、電子署名によって改ざんされていないことを保証します。
JWTは、ヘッダー.ペイロード.署名の3つの部分をピリオド(.)で結合した形式を持ちます。
ヘッダー (Header): トークンのタイプ(JWT)と、署名に使用するアルゴリズム(例:HMAC SHA256やRSA)が記述されます。
ペイロード (Payload): ユーザーID、権限、発行日時など、認証・認可に必要な情報(クレームと呼ばれる)がJSON形式で格納されます。
注意: ペイロードはエンコードされているだけで暗号化されていません。機密性の高い情報は含めないように注意が必要です。
署名 (Signature): ヘッダーとペイロードを、サーバーが持つ**秘密鍵(Secret Key)**と指定されたアルゴリズムでハッシュ化して生成されます。
サーバーは、この署名を検証することで、トークンが正当なサーバーによって発行されたものか、また途中で改ざんされていないかを確認できます。
C. JWTのメリット
スケーラビリティ: サーバー側で状態(セッション)を保持する必要がない(ステートレス)ため、サーバー台数を増やしてもセッション共有の手間がなく、スケールしやすいです。
クロスドメイン: Cookieの制限を受けず、モバイルアプリや異なるドメインのフロントエンド(SPAなど)からも利用しやすいです。
情報の内包: 必要なユーザー情報(権限など)をペイロードに含めることで、データベースへの問い合わせ回数を減らせる場合があります。
4. 認可の実装(アクセス制御)
認証によってユーザーが特定された後、そのユーザーに特定のリソースへのアクセスを許可するかどうかを判断するのが認可です。
ロールベースアクセス制御 (RBAC):
ユーザーに「管理者 (Admin)」「一般ユーザー (General)」「ゲスト (Guest)」などの**ロール(役割)**を割り当てます。
各リソースや機能に対して、「管理者ロールのみアクセス可能」といったルールを設定します。
属性ベースアクセス制御 (ABAC):
ユーザーの属性(部署、地域、役職など)、リソースの属性(作成者、機密レベルなど)、環境の属性(時間帯、IPアドレスなど)に基づいて、より柔軟なアクセス制御を行います。
この章では、Webアプリケーションの認証・認可の基本となるセッション/Cookieと、モダンなAPI開発で必須の**トークン認証(JWT)**について解説しました。これらの技術を使いこなすことが、安全でスケーラブルなバックエンドシステム構築の鍵となります。