Open1

認証と認可の違いを、JavaScriptで簡潔に整理する

Shota NukumizuShota Nukumizu

概要

私が大学時代にWEB開発のセキュリティに関することを学ぶ上で、最も理解に苦しんだ部分を簡潔にメモとして残す。

認証と認可の違い

一言で表現すると、「認証(Authentication)は誰か、認可(Authorization)は何ができるか」である。

  1. 認証:ユーザのアイデンティティを確認するプロセス。言い換えれば、ユーザが主張するアイデンティティを検証して、そのユーザが誰であるのかを確認することが目的。
  2. 認可:ユーザがアクセスできるリソースや機能を制御するプロセス。言い換えれば、認証されたユーザがシステム内で「できること」を決定するための権限やアクセスレベルを設定することが目的。

スクウェア・エニックスのRPG『ドラゴンクエスト』を具体例に検討する。

  1. 認証:プレイヤーが自分の冒険の書(いわゆるセーブデータ)を選択することで、そのデータを自分のものであることを示している。現実世界でのユーザ名とパスワードを使った認証を簡略化したもの。
  2. 認可:『ドラゴンクエスト』では、プレイヤーのパーティは異なるキャラクターで構成されていて、それぞれの役割や固有のスキルを持つ。たとえば、戦士は強力な物理攻撃ができるものの、呪文が使えない。一方で、魔法使いは強力な呪文を覚えるけど、物理攻撃があまり得意ではない。

これらのゲームシステムは、現実世界での認可の例に似ている。『ドラゴンクエスト』の職業では、職業ごとに特定のアクションや固有スキルへのアクセスが許可されていて、他のキャラクターの役割や固有スキルにアクセスできない。

上述の例であれば、戦士は「物理攻撃」というセッションにアクセスする権限は持っているものの、「呪文」というセッションにアクセスできないことを意味する。それぞれのユーザ(『ドラゴンクエスト』では、パーティメンバーに該当する)がシステム内、つまり『ドラゴンクエスト』のゲーム内でできることの権限が決められている状態が認可である。

JavaScriptのサンプル

認証(Authentication)

// ユーザー名とパスワードを擬似データベースから取得
const userDatabase = {
  "user1": {
    "username": "user1",
    "password": "password1"
  },
  // 他のユーザーも含まれています
};

function authenticate(username, password) {
  const user = userDatabase[username];
  
  if (user && user.password === password) {
    console.log("認証成功");
    return true;
  } else {
    console.log("認証失敗");
    return false;
  }
}

authenticate("user1", "password1");  // 認証成功
authenticate("user1", "wrongPassword");  // 認証失敗

認可(Authorization)

const permissions = {
  "user1": ["read", "write"],
  // 他のユーザーの権限も含まれています
};

function isAuthorized(username, action) {
  const userPermissions = permissions[username];

  if (userPermissions && userPermissions.includes(action)) {
    console.log("認可成功");
    return true;
  } else {
    console.log("認可失敗");
    return false;
  }
}

// 認証後、認可チェックを実行
if (authenticate("user1", "password1")) {
  isAuthorized("user1", "read");  // 認可成功
  isAuthorized("user1", "delete");  // 認可失敗
}

両者を区別する上で重要なポイント

認証は、アイデンティティ――要は、ユーザが誰であるかを検証すること。一方で、認可はアクセスを制御すること。

// 認証: アイデンティティの検証
function authenticate(username, password) {
  const user = userDatabase[username];
  
  // このif文でユーザのアイデンティティを検証している
  // ログインはこれと同じような原理
  if (user && user.password === password) {
    console.log("認証成功");
    return true;
  } else {
    console.log("認証失敗");
    return false;
  }
}

// 認可: アクセス制御
function isAuthorized(username, action) {
  const userPermissions = permissions[username];

 // このif文で、認可のロジックを簡潔に表現している
 // userPermissions変数のデータに、actionsの要素が含まれているかどうかで認可ロジックを実装
  if (userPermissions && userPermissions.includes(action)) {
    console.log("認可成功");
    return true;
  } else {
    console.log("認可失敗");
    return false;
  }
}

まとめ

  • 認証(Authentication)はユーザが「誰」であるかを確認すること
  • 認可(Authorization)はユーザが「できること」をコントロールすること