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

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

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

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

Q&A

解決済

1回答

2100閲覧

opauthでログイン状態を保持

atsupoooon

総合スコア47

CakePHP

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

1グッド

0クリップ

投稿2016/02/12 12:54

編集2016/02/13 15:05

Cakephp 2.6

opauthを利用して、ログイン状態を保持したいのですのがどよようにすれば良いのでしょうか。

access_tokenを取得して、
Appcontrollerで
access_tokenの有無を判定して、
なければログインページへリダイレクト。
みたいな感じでしょうか。

Sessionとかも使うのでしょうか。

イメージからつかめていません。
教えて頂けますでしょうか。

ikuwow👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

###2016/02/15

opauthを利用して、ログイン状態を保持

opauthは認証機構です。
認証に成功したら、あとはAuthComponentでログイン管理して下さい。


以下opauthのCakePHP用プラグインはすでに実装済みという前提で書きます。

access_token等の認証関連のややこしい部分は全てopauthがやってくれます。
実装の際はcallback用のメソッド内で$this->request->dataを用いて処理していくだけです。

PHP

1// http://lvh.me/auth/○○○(twitterやfacebook等)にアクセス後、認証画面からのコールバック 2public function callback(){ 3 if(empty($this->request->data) || $this->request->data['validated'] === false){ 4 // 認証失敗 5 }else{ 6 // 認証成功 7 $options = array( 'contain' => array() 8 , 'conditions' => array( 'User.provider' => $this->request->data['auth']['provider'] 9 , 'User.uid' => $this->request->data['auth']['uid'])); 10 11 $item = $this->User->find('first', $options); 12 if(empty($item)){ 13 // 未登録アカウント。以下新規登録処理とか。 14 }else{ 15 // 登録済みアカウント。以下ログインさせてマイページへのリダイレクト処理とか。 16 $this->Auth->login($item['User']); 17 } 18 } 19}

Sessionを使うかどうかですが、見ての通り基本は使わなくてOKです。
未登録アカウントは新規登録ページへリダイレクトするような仕様の場合、
provider、uidを持ちまわす為に使うことがあるかもしれません。

###2016/02/16 10:00 追記

PHP

1// http://lvh.me/auth/○○○(twitterやfacebook等)にアクセス後、認証画面からのコールバック 2public function callback(){ 3 if(!is_null($this->Auth->user())){ 4 // すでにログイン済み 5 $this->redirect($this->Auth->loginRedirect); 6 } 7 8 if(empty($this->request->data) || $this->request->data['validated'] === false){ 9 // 認証失敗 10 throw new UnauthorizedException('認証に失敗しました。'); 11 }else{ 12 // 認証成功 13 $options = array( 'contain' => array() 14 , 'conditions' => array( 'User.provider' => $this->request->data['auth']['provider'] 15 , 'User.uid' => $this->request->data['auth']['uid'])); 16 17 // ユーザー情報取得 18 $user = $this->User->find('first', $options); 19 20 if(empty($user)){ 21 // 未登録アカウントの為、新規登録。 22 $save = array( 'User.provider' => $this->request->data['provider'] 23 , 'User.uid' => $this->request->data['uid'] 24 , 'User.username' => $this->request->data['auth']['raw']['name']); 25 if($this->User->save($save)){ 26 // 登録したユーザー情報を再取得 27 $user = $this->User->find('first', $options); 28 }else{ 29 throw new InternalErrorException('新規登録に失敗しました。'); 30 } 31 } 32 33 // ログイン処理 34 if(!empty($user) && $this->Auth->login($user['User'])){ 35 $this->redirect($this->Auth->loginRedirect); 36 }else{ 37 throw new UnauthorizedException('ログインに失敗しました。'); 38 } 39 } 40}

コメントを踏まえて書くとこんな感じでしょうか。
ちなみに$this->request->data['auth']['raw']['name']はプロバイダによって存在しません。
例えばTwitterにはありますが、DropBoxにはありません。
使用されるプロバイダ毎に取得出来るデータをご確認下さい。

投稿2016/02/15 01:13

編集2016/02/16 00:55
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

atsupoooon

2016/02/15 07:47

回答ありがとうございます。 早速実施してみます。 1点質問があるのですが、 一度ログインをすると、ブラウザを閉じても認証されたままになるのでしょうか。 access_token等を保存するテーブルなどを作る必要があるのでしょうか。
退会済みユーザー

退会済みユーザー

2016/02/15 08:02 編集

>ブラウザを閉じても認証されたままになるのでしょうか。 それは各種SNS等のOAuth設定画面にて設定出来ます(設定出来ない所もあります)。 >access_token等を保存するテーブルなどを作る必要があるのでしょうか。 opauthを使用する上でaccess_tokenを気にすることはありません。 保存しなくてOKです。 しかしながらユーザー登録する場合はproviderとuidをセットでユーザーを一意に特定出来るようにデータベースに所持してください。 上記のコードの通り、その二つをもってユーザーを特定抽出しログインさせます。
atsupoooon

2016/02/15 13:15

ユーザー登録をしたいと思っています。 認証後に、saveでデータベースへ格納で問題ないですよね? なんとなく自分なりに考えて以下のように実装しました。 データベースにusernameとproviderとuidを格納しました。 public function callback() { if(empty($this->request->data) || $this->request->data['validated'] === false){ // 認証失敗 echo '再度認証してください。'; }else{ //認証成功 $options = array( 'contain'=> array(), 'User' => array( 'username' => $this->request->data['auth']['raw']['name'], 'provider' => $this->request->data['auth']['provider'], 'uid' => $this->request->data['auth']['uid'])); $item = $this->User->find('first', $options);        //データベースへnameとproviderとuid格納 $fields = array('username','provider','uid'); $this->User->save($options, false, $fields); if(empty($item)){ // 未登録アカウント。以下新規登録処理とか。 }else{ // 登録済みアカウント。以下ログインさせてマイページへのリダイレクト処理とか。 $this->Auth->login($item['User']); } } } 上記の記述でデータベースへ格納ができました。 合っていますでしょうか。 あと、ログイン前の処理ですが、 現在AppControllerでindexとloginは閲覧可能にしています。 public function beforeFilter() { parent::beforeFilter(); // 閲覧許可するページ $this->Auth->allow('index','login'); } indexとlogin以外のページを閲覧した場合、 例えばviewなどを閲覧した場合、コントローラーのviewのところに 条件分岐でログイン(ユーザー登録)の有無を判定する記述をすればよいのか。 AppController内で処理できるのでしょうか。 お教えいただけますでしょうか。 宜しくお願い致します。 長々すいません。
退会済みユーザー

退会済みユーザー

2016/02/16 00:01 編集

ちょっと今動かせる環境が無いのでパッと見た感じでの返事です。 ・ユーザーの新規登録の為のModel::save()は「if(empty($item))」の中です。 その位置ですと既存ユーザーの場合でも重複して登録してしまいます。 ・Model::save()の第2引数がfalseになっているためバリデートが動きません。正しい指定でしょうか? ・callbackメソッドもAppController内にあるのであれば、$this->Auth->allow()にはcallbackも含めて下さい。callbackの中でログインしますので、入って来た段階では未ログインの為弾かれてしまいます。(ログインした状態で認証画面に再度行ったのであれば弾かれませんが・・・) 最後の質問がちょっと分からなかったのですが、 $this->Auth->allow()にそのview指定していなければviewを閲覧した段階で弾かれるはずです。 ログイン判定してリダイレクトをかけるまでも無いかと思います。 Twitterを例としたフローです。 ・新規登録の場合 >http://lvh.me/auth/twitterへアクセス。 >Twitterの認証画面へリダイレクトされる。 >認証画面で許可する。 >http://lvh.me/auth/callbackへリダイレクトされる。 >認証成功ならprovider,uidを自サイトのユーザーから検索。 >該当ユーザー無しの為、新規登録。 >新規登録したそのユーザー情報で自サイトにログインするロジックを通過。 >新規登録&ログイン成功。 ・既存ユーザーのログインの場合 >http://lvh.me/auth/twitterへアクセス。 >Twitterの認証画面へリダイレクトされる。 >認証画面で許可する。 >http://lvh.me/auth/callbackへリダイレクトされる。 >認証成功ならprovider,uidを自サイトのユーザーから検索。 >該当ユーザー有りの為、そのユーザー情報で自サイトにログインするロジックを通過。 >ログイン成功。 こんな感じです。答えになってますでしょうか?
atsupoooon

2016/02/16 04:28

コメントありがとうございます。 ・ユーザ情報保存のsaveについて if文内に記述することで、重複がなくなりました。 重複まで考えいなかったです。 ・saveの第2引数は、わざとfalseにしておりました。 ・AppController内の$this->Auth->allow()にcallbackを追加することで、 ログイン済みの場合は、if文で指定したページにリダイレクトされました。 フローまでに記載していただきありがとうございます! 頭の中で、新規登録の際の処理と既存ユーザのログイン処理が ごっちゃになっていました。 自分のやりたい形に実装ができました。 ご指摘していただきありがとうございます!! もっと勉強したいと思います。 ありがとうございました! また、ご指導のほど宜しくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問