自動ログインの処理について
- 評価
- クリップ 6
- VIEW 4,691
会員サイトで一般ユーザーがアクセスできるすべてのページで自動ログインを実装しようと思っているのですが、自動ログインはしたことがなくて処理を洗い出してみたのですが、セキュリティー的な観点でだめなところやこうした方がいいなどありましたら教えていただけるとありがたいです。
※クッキーの有効期限やセキュアなどはシステム側で指定します。(fuelphpです)
クッキーがない場合
ログイン画面へ遷移させる
ログインする
ログインに使用したアドレスとパスワードがDBに存在するか確認する
存在する場合
ログインに使用したアドレスとパスワードを組み合わせてハッシュ化する
そのハッシュ値をクッキーに保存する
セッションを張って、トップページへ
存在しない場合
ログイン画面へ戻りそんな会員いねえよという
クッキーがある場合
クッキーに保存されているハッシュ値と、DBに保管されているアドレスとパスワードを組み合わせたハッシュ値が存在するか確認する。
一致する場合
ハッシュ値からアドレスとパスワードを復元し、自動ログインする
セッションを張って、指定ページを表示
一致しない場合
アクセス端末の情報と位置情報と改竄回数を取得しDB保存
改竄回数が3回以内の場合
クッキーを改竄している可能性があるとみなし、警告画面を表示させる
改竄回数が3回以上の場合
なにかしらの処理
修正後
■説明に必要なテーブル
user
id
name
surname
mail
password
user_token
(パスワード変更時に新規token発行とパスワード記録)
id
user_id
pwssword
token
limit
■おおまかな処理
クッキーがない場合
ログイン画面へ遷移させる
ログインする
ログインに使用したアドレスとパスワードがDBに存在するか確認する
存在する場合
ログインユーザーが所持するパスワードのトークンを取得
そのトークンをクッキーに保存する
セッションを張って、トップページへ
存在しない場合
ログイン画面へ戻りそんな会員いねえよという
クッキーがある場合
クッキーに保存されているトークンと、user_tokenにそのトークンが存在するか確認する。
存在する場合
user_tokenから遡りアドレスとパスワードを探し、自動ログインする
セッションを張って、指定ページを表示
存在しない場合
アクセス端末の情報と位置情報と改竄回数を取得しDB保存
改竄回数が3回以内の場合
クッキーを改竄している可能性があるとみなし、警告画面を表示させる
改竄回数が3回以上の場合
なにかしらの処理
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+8
ここですが、
ハッシュ値からアドレスとパスワードを復元し、自動ログインする
ハッシュ値から元の平文は復元できませんが、おそらくDBからアドレスとパスワードを求めるという意味だと解釈しました。これなら可能ですよね。
それは良いのですが、以下がよくありません。
ログインに使用したアドレスとパスワードを組み合わせてハッシュ化する
この方法ですと、ハッシュ値は、パスワードを変更しない限り同じものになります。そうすると、ハッシュ値の有効期限を設定することができなくなりますし、ハッシュ値があればいつでもどこからでもログインできるので、そういうむやみに強力なものをクッキーに保存することは好ましくありません。
なので、ハッシュではなく、トークンを使います。トークンは、要は乱数ですね。提示いただいた処理は、概ねハッシュを使わなくてもトークンでも実装できます。考えてみて下さい。
トークンは、有効期限を設けることができます。有効期限はデータベースに保存しておきます。また、何らかの問題が発生した場合は、トークンの無効化も簡単にできます。
追記します。トークンですが、単純化した実例を書いてみます。
メールアドレス | トークン | 有効期限 |
---|---|---|
tanaka@example.jp | 5b9636a4 | 2017/12/31 |
sato@example.jp | NULL | NULL |
takahashi@example.jp | a4f84d89 | 2017/12/01 |
yamada@example.jp | NULL | NULL |
ログインに成功したら、トークンをクッキーとして出力するとともに、DBには上記のように記録しておきます。これで分かりませんか?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
提示の方法では実装できないのではないでしょうか。
試しに実装してみればわかることだと思いますが、
ハッシュ値からアドレスとパスワードを復元
ここが致命的な欠陥です。
ハッシュは不可逆です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
そもそものログインの仕様が昨今のログインシステムで推奨されているやり方と違っています。
ログインに使用したアドレスとパスワードがDBに存在するか確認する
昨今のログインシステムに生パスワードは使用しません。
ハッシュ値の比較になります。
また、やろうとしていることは、セッションの自作にあたると思います。
この辺は自作しないほうが良いです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
一応ご承知かもしれませんが
Cookieを用いて自動ログイン、RememberMeトークンを保持するやり方は、
そのトークンの保持期間が通常のセッションIDより相当長期間になるかと思います。
通信の盗聴による漏洩リスクがあるので、ログインページのみではなく
全てのページをHTTPSとするデフォルトHTTPSとするか、
SetCookieヘッダにsecureフラグを指定してCookieの送出抑制することが望ましいです。
また、ブラウザを別の人と共有している人を考慮して、
自動ログインをするかどうかという情報をチェックボックスなどで選択してもらい、
トークンのCookieでの送出をしないという手続きが必要です。
その設定についてもCookieを使って保存しておき、
いちいちチェックを外さなくてもいいようにしてあげると外し忘れミスが減ります。
Remember-Me というワードで検索すると色々出てくると思いますので、
そちらのソースを参考にされると良いと思います。
http://fuelphp.jp/docs/1.9/packages/auth/examples/auth.html
http://fuelphp.jp/docs/1.9/packages/auth/simpleauth/usage.html#/method_remember_me
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/12/09 18:46
確かにパスワードは生涯固定でなければならなくなってしまいますね。
クッキーに保存される値は会員を識別できるものでなければならないのですが、乱数をクッキーに持たせてどうやって会員が存在するかを認識させるのでしょうか?
test@test.compasswordでハッシュ化すればどうにかして会員の存在確認はできると思ったのですが、、、
あ、会員のパスワードに対してトークンを持たせておいて、パスワードが変更されるたびにトークンも発行。
クッキー側のトークンもパスワードに紐つくトークンと比較して、そのパスワードは誰のもの?を拾って行けば実現できるとういうことですね。
2017/12/09 23:04
2017/12/10 00:34 編集
fuelPHPのAuth認証の場合、アドレスとトークンがメインということでしょうか?
パスワードを変更すると、、、という話が一番最初にあったと思いますが、編集いただいた回答の中でパスワードはどこにいきましたでしょうか?
2017/12/10 10:09
パスワードはいったん忘れましょう。パスワードをハッシュ値で保存する限り、正しいパスワードはサイト運営者にも分かりません。なので、パスワード以外の方法を使う必要があります。