これは Stackoverflow 全体で議論されていますが、これを機能させるための解決策を見つけることができませんでした。この投稿 ( CORS の問題。Flask <-> AngularJS ) で説明されていることの多くをフォローしようとしましたが、それは私のセットアップに密接に関連していたので、まだほとんど迷っています。
ローカルで実行されている python フラスコ API サーバーがあります。このドメインに bac-api という名前を付けました。この vhost は次のようになります。
<VirtualHost *:80>
ServerName bac-api
WSGIDaemonProcess bacapi python-path=/home/lumberjacked/workspace/bas/development/lib/python2.7/site-packages
WSGIScriptAlias / /home/lumberjacked/workspace/bas/development/bac-api/bacapi.wsgi
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, application/json"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS"
<Directory /home/lumberjacked/workspace/bas/development/bac-api>
WSGIProcessGroup bacapi
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
#SSLEngine on
#SSLCertificateFile /etc/apache2/ssl/bac_api_ssl.crt
#SSLCertificateKeyFile /etc/apache2/ssl/bac_api_ssl.key
</VirtualHost>
manage.bac という別のドメインでフロントエンドとして実行されている angularjs サイトがあります。私は、bac-api に接続し、ユーザーが認証されているかどうかをサーバーに尋ねる API キーおよび/またはユーザー資格情報を投稿する認証サービスを作成しています。
私はサーバーにカールすることができ、これは機能し、応答を返します。
curl -X POST -H "Content-Type: application/json" -d '{ "api": "7f3d6d7338b921ae4ca95cecc452ef1790005ec10c2343fabe5a59ea" }' http://bac-api/authenticated/
response -- {"authenticated": false}
また、manage.bac に移動し、ログイン クレジット email@email.com とパスワードを配置すると、同じ応答が返されますが、保存されたセッションで認証されていない場合は 401 を返すように構成されています。
POST http://bac-api/authenticated/ 401 (UNAUTHORIZED) bac-api/authenticated/:1
問題は、ssl 証明書とポート 443 に切り替えたときに始まります。そのため、両方のドメインで vhost をポート 443 に切り替え、ssl 証明書のコメントを外します。Apacheを再起動した後、エラーは発生せず、ドメインは500エラーなどを表示しない限り機能します。https を使用して bac-api サーバーにアクセスし、応答を取得できます。
curl -k -X POST -H "Content-Type: application/json" -d '{ "api": "7f3d6d7338b921ae4ca95cecc452ef1790005ec10c2343fabe5a59ea" }' https://bac-api/authenticated/
response -- {"authenticated": false}
しかし、https://manage.bacにアクセスしてログイン ページにリダイレクトするとすぐに、すべての問題が発生するようです。
コンソールがこのエラーをスローするログインフィールド内をクリックするとすぐに、それが関連しているかどうかわかりません。
Blocked a frame with origin "https://manage.bac" from accessing a frame with origin "chrome-extension://hdokiejnpimakedhajhdlcegeplioahd". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "chrome-extension". Protocols must match.
これは、いくつかのものを出力する console.log メソッドを使用した angularjs 認証コードです。
$http.post('https://bac-api/login/', user)
.success( function( user ) {
console.log('success');
console.log(user);
})
.error( function( error ) {
console.log('error');
console.log(error);
});
Object {email: "email@email.com", password: "password"} authentication-service.js:36
error authentication-service.js:50
authentication-service.js:51
このエラーが戻ってきたとき、応答には何もありません。OPTIONS をサーバーに送信しているため、このリクエストがプリフライトされていることを chrome ツールのネットワーク タブ内で確認できます。
OPTIONS /login/ HTTP/1.1
Host: bac-api
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: https://manage.bac
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-requested-with
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
また、[ネットワーク] タブでオプションとして表示され、キャンセルされていることがわかります。それが何を意味するのかわかりません。
これらのオプションを使用してangularjs内で構成しましたが、何の違いもないようです。
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
また、フラスコアプリケーション内で、ここで言及されているデコレータを実装しようとしましたhttp://flask.pocoo.org/snippets/56/および他のstackoverflowの投稿でも言及されています。これも何もしないようです。また、仮想ホスト内にAPIサーバーのアクセスヘッダーを配置したため、アプリで同じことを行う必要はないと思いました。自分が何をしているのかわからないので、完全に間違っている可能性がありますが。
どんな助けでも本当に感謝しています。これが重複した問題のように思われる場合は申し訳ありませんが、これまでのところこれを機能させることができず、この問題を解決できるすべての投稿をスタックオーバーフローで試しました。
--- 最新情報で編集
今朝、実験として、両方の vhost をポート 80 に戻し、すべての Allow access ヘッダーをコメントアウトしました。再起動して再度ログインしようとしましたが、これが私の結果です。
Failed to load resource: Origin http://manage.bac is not allowed by Access-Control-Allow-Origin. http://bac-api/authenticated/
XMLHttpRequest cannot load http://bac-api/authenticated/. Origin http://manage.bac is not allowed by Access-Control-Allow-Origin. manage.bac/:1
したがって、このエラーの後、bac-api vhost 内に移動し、コメントのないヘッダー セット Access-Control-Allow-Origin "*" を設定し、再起動してログインを試みました。表示される新しいエラーは次のとおりです。
OPTIONS http://bac-api/authenticated/ Request header field Content-Type is not allowed by Access-Control-Allow-Headers. angular.js:9312
(anonymous function) angular.js:9312
sendReq angular.js:9146
$http angular.js:8937
Authenticator.isLoggedIn authentication-service.js:13
RouteConfig.login.resolve.Auth state-service-provider.js:16
invoke angular.js:2902
(anonymous function) angular-ui-router.js:801
forEach angular.js:137
resolve angular-ui-router.js:797
resolveState angular-ui-router.js:813
transitionTo angular-ui-router.js:704
(anonymous function) angular-ui-router.js:615
invoke angular.js:2902
handleIfMatch angular-ui-router.js:433
rule angular-ui-router.js:452
update angular-ui-router.js:487
Scope.$broadcast angular.js:8307
afterLocationChange angular.js:5649
(anonymous function) angular.js:5637
Scope.$eval angular.js:8057
Scope.$digest angular.js:7922
Scope.$apply angular.js:8143
(anonymous function) angular.js:981
invoke angular.js:2895
resumeBootstrapInternal angular.js:979
bootstrap angular.js:993
angularInit angular.js:954
(anonymous function) angular.js:14843
c jquery-1.10.1.min.js:4
p.fireWith jquery-1.10.1.min.js:4
x.extend.ready jquery-1.10.1.min.js:4
q jquery-1.10.1.min.js:4
XMLHttpRequest cannot load http://bac-api/authenticated/. Request header field Content- Type is not allowed by Access-Control-Allow-Headers. manage.bac/:1
したがって、このエラーを解決して Content-Type を許可するには、bac-api vhost に戻り、Header set Access-Control-Allow-Headers "Content-Type" を追加します。ページの読み込み時に manage.bac へのブラウジングを再開した後の結果は次のとおりです。
POST http://bac-api/authenticated/ 401 (UNAUTHORIZED) bac-api/authenticated/:1
{"authenticated": false} 応答を受け取り、401 未承認を送り返したことを意味するため、これは良いことです。続行してログインしようとすると、これらの結果が得られます。
Object {email: "email@email.com", password: "password"} authentication-service.js:36
success authentication-service.js:40
Object {login: false} authentication-service.js:41
これも機能しています。この出力を生成する angularjs コードを次に示します。
$http.post('http://bac-api/login/', user)
.success( function( user ) {
console.log('success');
console.log(user);
})
.error( function( error ) {
console.log('error');
console.log(error);
});
ポート 80 で動作している場合、今すぐポート 443 に切り替えて、作業を続けることができれば、私の考えは素晴らしいものでした。そのため、vhosts をポート 443 に切り替え、manage.bac を再度参照してログインします。ログインしようとする前にページを読み込むと、これらの結果が得られます。
また、ログインしてフォームを送信しようとすると、これらの結果も得られます。
Object {email: "email@email.com", password: "password"} authentication-service.js:36
error authentication-service.js:50
authentication-service.js:51
また、[ネットワーク] タブでも
これは、私がこの問題の原因を見つけるのを助けるために、より多くの情報をすべての人に提供しようとするものでした.
----- より多くの情報を追加して再度編集
今夜、curl を使用してこれをテストし、OPTIONS リクエストでどのヘッダーが戻ってくるかを確認しようとしました。
これは、angularjs が送信している OPTIONS リクエストと同じであると仮定して、Network タブから直接コピーした curl リクエストです。まず、ネットワーク タブから OPTIONS リクエストを送信し、次に curl リクエストを送信します。
OPTIONS https://bac-api/login/ HTTP/1.1
Access-Control-Request-Method: POST
Origin: https://manage.bac
Referer: https://manage.bac/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36
Access-Control-Request-Headers: accept, origin, x-requested-with, content-type
curl -i -k -X OPTIONS -H "Access-Control-Request-Method: POST" -H "Origin: https://manage.bac" -H "Referer: https://manage.bac/" -H "Access-Control-Request-Headers: accept, origin, content-type" https://bac-api/login/
これがcurlからの応答です
HTTP/1.1 200 OK
Date: Tue, 01 Oct 2013 02:51:17 GMT
Server: Apache/2.2.22 (Ubuntu)
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Max-Age: 21600
Content-Length: 0
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: POST, GET, OPTIONS
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
これは、サーバーが正しく構成されており、正しいヘッダーで OPTIONS 要求に応答していることを示しているようです。しかし、上の写真に投稿したように、これをブラウザーでまだ [ネットワーク] タブで実行すると、キャンセルされ、エラー応答には何も返されません。