タイトル長い
タイトル通りの話。
Authのセッションが切れた後にAjaxでアクセスするとエラーが返ってきて、それ以上動作できない。
さらに、エラーのviewも返り、なんかキモいので、自分で作成したエラーメッセージとリダイレクトURLをJSONで渡せないかなと思ったのがきっかけ。
結構ハマったのでログに残す。
AngularJSのrequestをキャッチする
「あー、$this->request->is('ajax')
でキャッチすればいけんじゃね?」と思ったそこのあなた! 私ですかね?
できませんでした。理由はわかりませんが、以前似たようなことでハマったので、これではできないと(なんとなく)確信していました。
ただ、$this->request->input()
を使えば、postされた値は取れると。さらにjson_decode
をコールバックで渡してあげたら、もし値がjsonであれば、配列が返ってきます。
$angularAjax = $this->request->input('json_decode', true);
これでよし。通常のPOSTはname_1=test&name_2=test2
みたいな値で飛んで来るので、json_decode
ではnull
で返ってきます。それを利用して、リクエストが配列であれば、AngularJSからのリクエストという判定ができます。
これにプラス。認証しているかどうかを判定すればおk.認証の確認はセッションからAuthの情報を取り出します。
<?php $isAuth = $this->request->session()->read('Auth.User');
もし認証しているのなら、認証ユーザーの情報が配列で入っているはず。
完成したコードはこちら。これをAppController
のbeforeFilter
で記述すればおk.
<?php class AppController extends Controller { // ... 省略 public function beforeFilter(Event $event) { $isAuth = $this->request->session()->read('Auth.User'); $angularAjax = $this->request->input('json_decode', true); if (is_array($angularAjax) && ! $isAuth) { $this->autoRender = false; $this->response->charset('UTF-8'); $this->response->type('json'); $this->response->statusCode(400); echo json_encode(['message' => __('You must be login.')]); return $this->response; } return parent::beforeFilter($event); } // ... 省略 }
$this->response
を組み立てて最後にreturn
で返します。これでおk.これでできました。
ちなみに。。。書いてていくつか思ったこと。
そもそも、400ステータスは確認できていたので、そのままリダイレクトすればよかったんじゃ。。。。?
まぁでもやっぱしエラーのviewがブラウザのコンソールに流れてくるので、やっぱりこれでいいかな。
あー、そういえば、HTTP GETメソッドをAjaxで飛ばされたらこれキャッチできないんじゃね・・・・? できないと思います。。。これは一旦確かめてもしできなかったら、この記事に追記します。こうご期待(?)
追記 2016/09/14
やっぱりGETメソッドでは上のコードは動きませんでした。。。。さてどうすべ?と悩んでいました。
よく考えると、PHPでAjaxを判定する場合はどのパラメータを確認できればいいのか? などなど考えているといくつか記事に出会いました。
jQuery、prototypeなどのライブラリを利用してAjax通信をした場合、 リクエストヘッダーに「X-Requested-With:XMLHttpRequest」がセットされるため
AngularJSで来たリクエストを確認したら
<?php // null env('HTTP_X_REQUESTED_WITH');
(´・ω・`)
次にHTTP_X_REQUESTED_WITH
は何故AngularJSで取れないの?と思ったので、angularjs HTTP_X_REQUESTED_WITH
で検索したところ
おおー!と感激していたら、コメントに
$httpProvider でデフォで X-Requested-With が付くようにするのでも良いかもしれませんね
なんと! AngularJSでは意図的に送信しないようになっていたのね。
ということでconfig
で設定するようにしました。
/** * Added X-Requested-With Default */ .config(['$httpProvider', function($httpProvider){ $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; }]);
そしたら取れたキタ━━━━(゚∀゚)━━━━!!