認証
セキュアなトークンをやり取りする要件(cookiesを盗む方法)
気をつけること
Secure Sockets Layer (SSL) をサイト全体に適用して、ネットワークデータを暗号化で保護し、パケットスニッファから読み取られないようにする。 記憶トークンをそのままデータベースに保存するのではなく、記憶トークンのハッシュ値を保存する。 これは、生のパスワードをデータベースに保存する代わりに、パスワードのダイジェストを保存したのと同じ考え方。
ユーザが入力した内容を画面に表示するような作りがある時に、<script>console.log('A');</script>なんかを入力して、表示した時にインジェクションを仕掛ける対策。
Railsが入力値を自動的にエスケープすることで対策が行われている。 ユーザーがログインしているパソコンやスマホを直接操作してアクセスを奪い取る。
さすがにシステム側での根本的な防衛手段を講じることは不可能。
二次被害を最小限に留めるために、ユーザーが (別端末などで) ログアウトしたときにトークンを必ず変更するようにし、セキュリティ上重要になる可能性のある情報を表示するときはデジタル署名 (digital signature) を行うようにする。 Railsチュートリアル式の記憶トークン取り扱い
記憶トークンにはランダムな文字列を生成して用いる。
SecureRandom.urlsafe_base64
ブラウザのcookiesにトークンを保存するときには、有効期限を設定する。
code:rb
expires: 20.years.from_now.utc }
トークンはハッシュ値に変換してからデータベースに保存する。
code:ruby
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
ここで言うcostはどれだけ復号化しにくいハッシュにするのかの係数。
ここでは、開発時は軽く、本番時は重くしている
受け取ったトークンとハッシュが一致しているか確認する時(認証する時)
ブラウザのcookiesに保存するユーザーIDは暗号化しておく。
cookies.signed[:user_id] = user.id
永続ユーザーIDを含むcookiesを受け取ったら、そのIDでデータベースを検索し、記憶トークンのcookiesがデータベース内のハッシュ値と一致することを確認する。
code:rb
user = User.find_by(id: cookies.signed:user_id) BCrypt::Password.new(remember_digest).is_password?(remember_token)
パスワード認証
入力されたパスワードをハッシュ化して保存
ログイン時は入力されたパスワードをハッシュ化して、保存したものと突合する
トークンを使った同一性担保
認証メールの時など、セッションが切れた後も同一性を担保したい時の仕組み。
トークンという形で、プログラムでパスワードを発行して、パスワードが一致すれば同一セッションと扱う。
認証メールの例
1. トークン(パスワード)の発行
2. トークンをハッシュ化してDBへ保存
3. 認証メールのURLにトークンを付与
4. アクセスがあった時に、受信したトークンをハッシュ化してDBと突合する
ログイン記憶の例
1. トークンの発行
2. トークンをハッシュ化してDBへ保存
3. トークンをcookieに保存
4. 次回アクセス時にcookieからトークン取得
5. 取得したトークンをハッシュ化してDBと突合する
パスワード再発行の例
1. ユーザーにメールアドレスを入力してもらう
2. トークンの発行
3. 入力されたメールアドレスに紐づくレコードへ、トークンのハッシュを保存
4. 認証メールのURLに、トークンを付与
5. アクセスがあった時に、受信したトークンをハッシュ化してDBと突合する
ID生成大全
Basic認証
認証
ID/パスワード
ID/パターンロック
ID/秘密の質問
メール受信
MACアドレス(モバイル不可)
Android_ID / IDFV(Identifier For Vender)
UUID
認可
認証とは違い、この人は何が出来るか、何が出来ないかの権限の話
(認証は「あなたは誰?」を確認する話)
認可の事を authorization 認証の事は authentication ややこしい
認証サーバを別に用意して、複数サービス間で認証情報を共有する作り