3秒でわかる
アクセスしてきた相手が名乗ったとおりの本人かを確かめる仕組み。パスワードや生体情報で身元を確認し、その後の権限判定の土台になります。
30秒図解
もう少し詳しく
どういうものか
認証は、利用者やシステムが「誰であるか」を確認する処理である。英語では authentication と呼び、AuthN と略される。
確認に使う材料は 3 つの要素に分類される。知識情報 (パスワード、暗証番号)、所持情報 (スマートフォン、IC カード、ハードウェアキー)、生体情報 (指紋、顔) である。このうち異なる 2 種類以上を組み合わせる方式を多要素認証と呼ぶ。パスワードと秘密の質問はどちらも知識情報なので、2 つ使っても多要素にはならない。
なぜ必要か
認証が無いと、誰でも他人のデータを読み書きできる。逆に言えば、権限の判定 (認可) は認証の結果があって初めて成立する。誰か分からない相手に対して「この人は管理者か」は判定できない。
そしてパスワードだけでは足りない。使い回されたパスワードは、他のサービスから漏れた組み合わせをそのまま試す攻撃で破られる。所持情報を 1 つ足すだけで、この種の攻撃はほぼ止まる。
具体例
import bcrypt from "bcrypt";
// 登録時 ── 平文は保存せず、ハッシュだけを保存する
const hash = await bcrypt.hash(plainPassword, 12);
await db.users.insert({ email, passwordHash: hash });
// ログイン時 ── 入力値をハッシュと突き合わせる
const user = await db.users.findByEmail(email);
const ok = user ? await bcrypt.compare(plainPassword, user.passwordHash) : false;
if (!ok) {
// 「メールアドレスが存在しません」と「パスワードが違います」を
// 区別すると、登録済みのアドレスを探られる
return res.status(401).json({ message: "メールアドレスまたはパスワードが違います" });
}
req.session.userId = user.id; // 認証済みであることを<a href="/glossary/session" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">セッション</a>に記録するつまずきやすいところ
パスワードを平文や可逆な暗号化で保存してしまう設計が最も重い。保存には bcrypt や Argon2 のような、計算に時間がかかるよう設計されたハッシュ関数を使う。SHA-256 単体は高速すぎて総当たりに耐えない。
もう 1 つ、ログイン後の状態管理を忘れがちである。認証はログインの瞬間だけの処理で、その後のリクエストが同じ人物かはセッション ID やトークンで保つ。ここが弱いとセッションハイジャックの的になるため、Cookie には HttpOnly と Secure と SameSite を付ける。
似た用語との違い
| 語 | 問い |
|---|---|
| 認証 (Authentication) | あなたは誰か |
| 認可 (Authorization) | あなたは何をしてよいか |
| 識別 (Identification) | どのアカウントを名乗っているか |
OAuth 2.0 は本来 認可 の枠組みで、認証として使うには OpenID Connect を重ねる。ここを取り違えた実装は、他人のアクセストークンで別人になりすませてしまう。