質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

1回答

982閲覧

Cakephp3で多重認証(ログイン)ができなくなるようにしたいです。

lovelydai

総合スコア38

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

3クリップ

投稿2017/10/24 02:32

編集2017/10/25 08:33

こんにちは、Cakehphp3で時間割システムを開発しています。

Cakephp3のAuthコンポーネント(?)を使い、認証機能を実装しました。
そこで、テストしてみたら一つのアカウントで複数のパソコンもしくは同じパソコンの複数のブラウザー(例えば、ChromeとEdgeなど)で重複してログインができ、別々セッションが作られます。(同じブラウザーでは、’すでにログイン状態です’とエラーを表示するようにしています。)
Session価を確認してみると、AuthのUser配列に入ってる値は同じですが、Configという配列にTime価は異なることが分かりました。

同時に同じアカウントで複数人が接続するのは困りますので多重認証を防ぐために何かの処理をしたいのですが、Cakephp3では何か設定方法ありませんか?マニュアルを探してみましたが情報は見つかりませんでしたし、ググってみても普通のPHPやJQueryコードばかりでしたので質問致します。
希望は、後にログインする方が勝ちというか、ログインした時にもし同じアカウントですでにログインされている場合は新しいログイン情報に更新し、古いやつは強制的にログアウンと&セッション削除するなどの処理ができればいいですが。

アドバイスいただけると幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。
やり方はたくさんあるようですが、私はトークンを使うことで解決しました。
認証する時にランダムでトークンを発行し、それをDBに入れると同時にsetUser()で認証をします。
ログアウトする時はDBのトークンとセッションを破棄する。
あとは、AppControllerのBeforeFilterにセッションが持つトークンとDBにあるトークンをチェックし、一致しなかった場合(誰かログインしてDBのトークンが更新されてしまった場合)は、二重認証だと判断し、セッションを破棄させて強制的にログアウトさせる、という形で実装しました。
すべてのページにてセッションとDBのトークンを比較するのでパフォーマンスは低いと思いますが、自分の実力ではこれがベストかな、と。(涙)

PHP

1// UsersControllerのLogin()中 2// ログインの時間制限があるのか判断するための処理(例外処理必要) 3 $query = $this->Users->find()->where( 4 ['account' => $this->request->data['account'], 5 'customer_no' => $this->request->data['customer_no'] 6 ]); 7 $targetUser = $query->first(); 8 9   $this->Users->initUser($targetUser); // トークンを発行するためのFunction 10 $user = $this->Auth->identify(); 11 if ($user) 12 { 13 $this->Auth->setUser($user); 14 return $this->redirect($this->Auth->redirectUrl()); 15 } 16 17// UsersControllerのLogout()中 18// ログイン状態の利用者情報をセッションから読み取る。 19 $account = $this->Auth->User('account'); 20 $customer_idx = $this->Auth->User('customer_idx'); 21 // DBのTokenをNullに更新 22 $query = $this->Users->query(); 23 $query->update() 24 ->set(['token' => null, 25 'modifier' => $account, 26 'modified' => Time::now()]) 27 ->where(['customer_idx' => $customer_idx, 'account' => $account]) 28 ->execute(); 29 30 //ログアウト処理、セッションを消してログインページに移動させる。 31 $this->request->session()->destroy(); 32 $this->Flash->success(__('成功的にログアウトしました。')); 33 return $this->redirect($this->Auth->logout()); 34 35// UsersTable.phpのinitUser()の定義 36 public function initUser($targetUser) 37 { 38 //ログイン成功時、ランダムでトークンを発行する。 39 $token = hash('sha256', date("YmdHis").$_REQUEST['customer_no']); 40 $target->token = $token; 41 42 $this->save($targetUser); 43 } 44 45// AppController.phpのBeforeFilter 46public function beforeFilter(Event $event) 47{ 48 // 二重認証をチェックする 49 // セッションとトークンをチェックしてなかったら強制ログアウト、 50 // あればセッションのトークン値とDBのトークン価を比較する。 51 // トークン値が一致する場合は何もしなくていい、 52 // 不一致する場合はそのセッションを破棄しログインページに戻す。 53 54 // セッションを比較するための準備 55 $session_token = $this->Auth->user('token'); 56 if(isset($session_token)) 57 { 58   $account = $this->Auth->user('account'); 59 $customer_idx = $this->Auth->user('customer_idx'); 60 61 $query = $this->Users->find()->where( 62    ['account' => $account, 63 'customer_idx' => $customer_idx 64 ]); 65 $user = $query->first(); 66 67 $db_token = $user->token; 68 // セッションのトークン価とDBのトークン価が一致しない場合は、強制的にログアウトさせる。 69 if($session_token != $db_token) 70 { 71 $this->Session->destroy(); 72 $this->Flash->warning(__('トークン価が更新されましたのでログアウトされました。')); 73 $this->redirect($this->Auth->logout()); 74 } 75 } 76}   77

投稿2017/10/30 00:56

lovelydai

総合スコア38

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問