Angular.js×cakePHP3.xで非同期通信の実装 その2

カテゴリ:

公開日:2020.06.23 最終更新日:2020.07.30
このエントリーをはてなブックマークに追加

こんにちは。inglowの開発担当です。
今回は、前回に引き続き、javascriptのライブラリ「Angular.js」とcakePHP3.xを利用した場合の非同期通信の処理を生成する第二回目です。第一回目の記事はこちらです。
Angular.js×cakePHP3.xで非同期通信の実装 その1

今回使った技術は下記です。

  • PHP(cakePHP3.8)
  • javascript(angular.js)

目次

Angular.js×cakePHP3.x

前回は、フォームのsubmit時に「ng-submit」で指定した処理が動くようにしました。
しかし、この処理で非同期通信でデータを送信すると、「CSRFトークンが一致していない」というエラーが返ってくるかと思います。

今回は、このcakePHP3.xの「CSRF対策」をどう共存させていくかという点を書いていきたいと思います。

cakePHP3のCSRF対策

cakePHP3.xでは、CSRF対策は「ミドルウェア」と呼ばれるもので動くようになっています。
このミドルウェアは、routes.phpでスコープ毎(プレフィックスや特定のcontrollerの指定)に読み込むかどうかを指定します。
cakePHPのプロジェクトを生成したばかりのデフォルトの場合はアプリケーション内すべてのURLでCSRF対策が動くようになっています。
今回は、

の2通りのやり方を試してみました。

方法その1 CSRFミドルウェアの設定を変更する

アプリケーション全体でCSRF対策をしない場合は、routes.phpのミドルウェア読み込み部分をコメントアウトするだけでOKです。

しかし、ブラウザで表示するページまでCSRFチェックされない状態が良くない場合もあります。その場合は、prefixを分けて設定をします。
まず、routes.phpで非同期通信用のプレフィックスを用意します。
今回は[app/api/…..]というURLになるように変更していきます。

ミドルウェアの記載をしなければ、これで「app/api/~」のURLの処理はCSRFチェックなしで非同期通信ができます。
あとは、src/Controller/Api/の階層を作成し、Controllerを作成していきます。
この方法であれば、通常の画面にはcakePHPのCSRFチェックを使い、APIの通信の場合は使用しない状態にできます。ただし、外部のどんなURLからでもPOSTできる状態になってしまうので、リファラーでドメイン名をチェックしたり、自分でトークンチェックの仕組みをする必要があります。

方法その2 CSRF対策のトークンを一緒に送信する

「jquery cakePHP ajax」で調べるとよく見つかる方法です。anguler.jsの場合はどうなるのか試してみました。

まずは、通信の前にcsrfトークンを取得する処理を書いていきます。

次に、取得したCSRFトークンを通信する際のヘッダーに設定します。

最後に通信処理を記載したらOKです。
全容はこのような感じになります

この方法の場合は、トークンチェックをcakePHPに任せているので自分で特別処理を書く必要はありませんが、一度FormヘルパーでForm->create()をする必要があります。

さいごに

どちらの方法も一長一短という感じです。
例えば、外部のアプリケーションからも通信できるようにするのであれば、「方法1」、モーダルウィンドウを出して入力内容を通信したいという場合であれば「方法2」という感じになるかなと思います。
非同期通信でのCSRFチェックの共存は、Angular.jsを利用する場合にcakePHPを利用するにあたって避けては通れない部分だったので、まとめてみました。

この記事のあとによく読まれています

一覧へ戻る