2016-12-29 11 views
2

私は、CakePHP 2.8で実装されたREST APIと会話するIonic 1アプリを構築しています。認証にはJSON Web Tokens (JWT)を使用しています。CakePHP2:CORSプリフライトの問題JWT Auth

私のアプリは無許可の状態で、問題なくサーバにGET/POSTリクエストを行うことができます。しかし、一度私は認証し、私のアプリはすべての要求と一緒にauthTokenヘッダーを送信している、Angularは自動的にOPTIONSプリフライトリクエストを送信します。

ここで問題が始まります。自動プリフライト要求にはauthTokenヘッダーが設定されていないため、APIエンドポイントで承認が必要なため、CakePHPは/loginに302 FOUNDリダイレクトで応答します。アプリ(またはこのテスト段階のブラウザ)は、これを安全でないと判断し、適切なリクエストを行うことはありません。

私の質問: AngularJSがクロスドメインサーバにカスタムヘッダを安全に送ることができるように、CakePHPにプリフライトOPTIONS要求に適切に対応させるにはどうすればよいですか?

リクエストヘッダ:

Origin: http://yourdomain.com 
Access-Control-Request-Method: POST 
Access-Control-Request-Headers: X-Custom-Header 

レスポンスヘッダ:私が試した事

Access-Control-Allow-Origin: http://yourdomain.com // Same as origin above 
Access-Control-Allow-Methods: GET, POST 
Access-Control-Allow-Headers: X-Custom-Header 

this questionごとに、これが起こることを必要とするものです設定中.htaccessは、OPTIONSリクエストには常に200で応答します。 200レスポンスが返ってきますが、レスポンスには「あなたのサーバは正しく設定されていません」と表示され、適切なヘッダが設定されていないため、実際の$httpリクエストは決して通過しません。

-リクエストに常に一定の方法で応答するCakePHPの取得。ここでの問題は、Cakeに承認をスキップさせ、コントローラアクションを実行しようとするのをスキップし、適切なヘッダーが設定されたHTTP 200応答を返送することです。好奇心のために

// AppController::beforeFilter(); 
    if($this->request->is("options")){ 
     // Send the appropriate response based on the request 
    } 

、ここで失敗した$http要求の過程で交換され得るヘッダは以下のとおりです。

GENERAL: 
Request URL:https://api.example.com/rest_users/profile.json 
Request Method:OPTIONS 
Status Code:302 Found 
Remote Address:x.x.x.x:443 

REQUEST HEADERS: 
Accept:*/* 
Accept-Encoding:gzip, deflate, sdch, br 
Accept-Language:en-US 
Access-Control-Request-Headers:authtoken 
Access-Control-Request-Method:GET 
Cache-Control:no-cache 
Connection:keep-alive 
DNT:1 
Host:api.example.com 
Origin:http://x.x.x.x:8100 
Pragma:no-cache 
Referer:http://x.x.x.x:8100/ 
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36 


RESPONSE HEADERS: 
Access-Control-Allow-Headers:Content-Type, x-xsrf-token 
Access-Control-Allow-Methods:* 
Access-Control-Allow-Origin:* 
Access-Control-Max-Age:172800 
Connection:Keep-Alive 
Content-Encoding:gzip 
Content-Length:20 
Content-Type:text/html; charset=UTF-8 
Date:Thu, 29 Dec 2016 18:51:30 GMT 
Keep-Alive:timeout=15, max=99 
Location:https://api.example.com/login 
Server:Apache/2.2.15 (CentOS) 
Vary:Accept-Encoding 
X-Powered-By:PHP/5.3.3 
+0

まず:あなたはおそらく '代わりにカスタムのauthtoken'ヘッダーをより一般的な' Authorization'ヘッダーを使用する必要があります。第2: 'Access-Control-Allow-Headers:Content-Type、x-xsrf-token' ...あなたのカスタム' authtoken'ヘッダを送ることが許可されていません。許可されたリストにはありません。それはおそらく問題です。 – TheSharpieOne

+0

私は 'Access-Control-Allow-Origin:x.x.x.x'(一般にIPアドレス)ヘッダーを応答に設定する必要があります。ワイルドカードにすることはできません。リクエストはアプリから送信されるため、ヘッダーをカスタマイズする必要があります。 – schnauss

+0

'Access-Control-Allow-Origin'は通常IPアドレスではありませんが、通常はドメイン名です。あなたがIPアドレス(URLバー)でサイトにアクセスしている場合を除き、完全修飾ドメイン名になります。 '*'はテストのためにうまくいきます。後でそれをロックしたいでしょう。しかし、それはここにもそこにもありません。あなたがなぜそれを持ってきたのか分かりません。私は、Access-Control-Allow - ** Headers **について話していましたが、現在は 'authtoken'ヘッダーを送信できません。あなたの要求はあなたの設定で許可されていないので、 – TheSharpieOne

答えて

0

私はCakePHPが正しくCORSのpreflightsを処理することを可能にする解決策を見つけました。要求されたアクションが実行される前に、ヘッダーを設定し、応答を送信し、Cakeをシャットダウンします。

このコードが実行されるように、すべてのコントローラに必ずparent::beforeFilter();があることを確認してください。 AppControllerで

::のbeforeFilter():

if($this->request->is("options")){ 
     // Set the headers 
     $this->response->header('Access-Control-Allow-Origin','*'); 
     $this->response->header('Access-Control-Allow-Methods','*'); 
     $this->response->header('Access-Control-Allow-Headers','Content-Type, Authorization'); 
     // Send the response 
     $this->response->send(); 
     // Don't do anything else! 
     $this->_stop(); 
    } 
+0

[**ディスパッチャフィルタ**](http://book.cakephp.org/2.0/ja/development/dispatch-filters.html)と[** 'CakeResponse :: cors( ) '**](http://api.cakephp.org/2.8/class-CakeResponse.html#_cors)。 – ndm

関連する問題