タイトル長い
タイトル通りの話。
Authのセッションが切れた後にAjaxでアクセスするとエラーが返ってきて、それ以上動作できない。
さらに、エラーのviewも返り、なんかキモいので、自分で作成したエラーメッセージとリダイレクトURLをJSONで渡せないかなと思ったのがきっかけ。
結構ハマったのでログに残す。
AngularJSのrequestをキャッチする
「あー、$this->request->is('ajax')
でキャッチすればいけんじゃね?」と思ったそこのあなた! 私ですかね?
できませんでした。理由はわかりませんが、以前似たようなことでハマったので、これではできないと(なんとなく)確信していました。
www.aipacommander.com
ただ、$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を判定する場合はどのパラメータを確認できればいいのか? などなど考えているといくつか記事に出会いました。
note.onichannn.net
jQuery、prototypeなどのライブラリを利用してAjax通信をした場合、
リクエストヘッダーに「X-Requested-With:XMLHttpRequest」がセットされるため
AngularJSで来たリクエストを確認したら
<?php
env('HTTP_X_REQUESTED_WITH');
(´・ω・`)
次にHTTP_X_REQUESTED_WITH
は何故AngularJSで取れないの?と思ったので、angularjs HTTP_X_REQUESTED_WITH
で検索したところ
qiita.com
おおー!と感激していたら、コメントに
$httpProvider でデフォで X-Requested-With が付くようにするのでも良いかもしれませんね
なんと! AngularJSでは意図的に送信しないようになっていたのね。
github.com
ということでconfig
で設定するようにしました。
.config(['$httpProvider', function($httpProvider){
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}]);
そしたら取れたキタ━━━━(゚∀゚)━━━━!!