私は独学で JavaScript / Node.js / Express を勉強中です。
現在は Udemy のハンズオン教材をベースにしながら、実際にキャンプ場アプリを開発しています。
このブログでは![]()
- 学習中に理解できたこと
- 実装してみて気づいたこと
- 詰まったポイント
- 実際のコード例
などをアウトプットしていこうと思います。
今回は Express の「認証(Authentication)」と「認可(Authorization)」、そしてパスワードのハッシュ化についてまとめます。
Chapter1 認証(Authentication) と 認可(Authorization)
どんなアプリでも重要になるのが、
認証(Authentication)
認可(Authorization)という2つの概念です。
認証(Authentication)→「あなたは誰ですか?」を確認する仕組みです。
例えば:
ログイン
ユーザー登録
パスワード確認
メール認証
などが該当します。つまり、who are you ? を確認する処理です。
認可(Authorization)
認証後に、そのユーザーは何ができるのか?を決める仕組みです。
例えば:
投稿を編集できる
管理者ページに入れる
他人のデータは削除できない
などです。つまり、what can you do ?を決めるのが認可です。
パスワードをそのまま保存してはいけない ❌
開発を始めたばかりの頃は、
{
username: "test",
password: "123456"
}
のように、そのままデータベースへ保存したくなります。しかし、これは絶対に避けるべきです。もしデータベースが漏洩した場合、ユーザーのパスワード他サービスで再利用しているパスワードまで危険になります。
実際、多くのユーザーは同じパスワードを複数サービスで使い回しています。
そのため、パスワードは必ず「ハッシュ化」して保存する必要があります。
パスワードをハッシュ化する
パスワードを安全に保存するために使われるのが「ハッシュ関数」です。
mdn では次のように説明されています。
ハッシュ関数は、可変長の入力を受けて固定長の出力を生成する関数。
簡単にいうと、元の文字列を別の意味不明な文字列へ変換する仕組みです。
例えば:
password123
↓
a8f5f167f44f4964e6c998dee827110c
のようなイメージです。
ログイン時の流れ
ログイン時は次のような流れになります。
1. ユーザーがパスワードを作成
2. パスワードをハッシュ化
3. ハッシュ化された値をDBへ保存
4. ユーザーがログインを試す
5. 入力されたパスワードを再度ハッシュ化
6. DBの値と比較
7. 一致すればログイン成功
つまり、アプリ側も「元のパスワード」を保存しているわけではありません。
ハッシュ化しても完全ではない
ハッシュ化すると安全性はかなり上がります。しかし、完全ではありません。
攻撃者は事前に大量のパスワードをハッシュ化した「レインボーテーブル(ハッシュテーブル)」を使い、照合を試す場合があります。
Salt(ソルト)
そこで重要になるのが「Salt」です。Salt は、ハッシュ化する前に追加するランダムな文字列です。
例えば:
password123 + x7K9Lm
のように、ランダム値を加えてからハッシュ化します。
これによって、同じパスワードでも毎回異なるハッシュ値になるため、攻撃がかなり難しくなります。また重要なのは、
ログイン時には「同じアルゴリズム」と「保存されているSalt」を使って、再度ハッシュ化する必要があるという点です。
ハッシュ関数は、
- 同じ入力
- 同じSalt
- 同じハッシュアルゴリズム
を使った時だけ、同じ結果になります。
学習して感じたこと
最初は、
「ログイン機能を作る = username と password を比較するだけ」と思っていました。
しかし実際には、
- ハッシュ化
- Salt
- 認証
- 認可
- セッション管理
- Cookie
など、多くのセキュリティ知識が必要でした。特になぜその実装が危険なのか
を理解することが大事だと感じています。
次回
次回は実際に Express / Passport を使ったログイン実装についてまとめようと思います。