2017-10-22 12 views
0

個人アカウント認証テンプレートを使用してWebApiアプリケーションを作成し、さまざまなクライアントが自分のサービスを使用できるようにCORSを有効にしました。私はすべての起点( "*")を許可するようにCORSを設定しました。また、安全なルートを呼び出すときに使用するトークンを正常に取得するAngularフロントエンドを作成しました。ただし、フライト前のチェックが失敗したため、クライアントはログアウトアクションを呼び出すことができません。プリファイライトは1つのAngularクライアントで失敗しますが、別のクライアントでは失敗します

問題のトラブルシューティング中に、this articleに記載されている手順を使用して別のソリューションを作成しました。新しいソリューションはすごくうまくいくので、私はクライアントの新しいソリューションをオリジナルのWebApiプロジェクトに指摘しました。これはAngularクライアント間に何か違うものがあると私に信じさせましたが、重要な違いは見当たりませんでした。

誰かが以下のコードを見直して、動作するクライアントと失敗したクライアントの違いを指摘できますか?

アプリケーション構成

app.config(['$httpProvider', function ($httpProvider) { 
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; 
    // Override $http service's default transformRequest 
    $httpProvider.defaults.transformRequest = [function (data) { 
    // Converts an object to x-www-form-urlencoded serialization. 
    }]; 
}]); 

私の工場では

var deferred = $q.defer(); 
$http({ 
    method: 'POST', 
    url: logoutUrl, 
    headers: getHeaders(), 
}).then(function (data, status, headers, cfg) { 
    accessToken = null; 
    deferred.resolve({ status: 'success' }); 
}, function (err, status) { 
    console.log(err); 
    deferred.reject(status); 
}); 
return deferred.promise; 

function getHeaders() { 
    if (accessToken) { 
     return { "Authorization": "Bearer " + accessToken }; 
    } 
} 

ここを通過する生のHTTPリクエストです:

これは働くアプリケーション内の角度のコードがあります。 OPTIONSプリフライトチェックが合格するので、POSTが実行されます。

OPTIONS http://localhost:56508/api/Account/Logout HTTP/1.1 
Host: localhost:56508 
Connection: keep-alive 
Access-Control-Request-Method: POST 
Origin: http://localhost:42458 
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 
Access-Control-Request-Headers: authorization 
Accept: */* 
DNT: 1 
Referer: http://localhost:42458/ 
Accept-Encoding: gzip, deflate, br 
Accept-Language: en-US,en;q=0.8 

POST http://localhost:56508/api/Account/Logout HTTP/1.1 
Host: localhost:56508 
Connection: keep-alive 
Content-Length: 0 
Accept: application/json, text/plain, */* 
Origin: http://localhost:42458 
Authorization: Bearer fNKcX_jCNhQuIhorMw-QPyezReQJd5ehoVhqegUmSQZxdbHp-T6L4RPehSl6ihSpNbYH58uhELwNHV0bEAyRj0G7bmFv4O5GIqBDyiOIB-YBfez5zHRNHbMe_iTdtBwdgOdbLh5PNSNIOi4ffU6H-py4oko0rMkLSP_hFSl2TGcbJwuJkrmHmahmLyeyQ-OO8KI4Kc-WoTaIVw3dJ5LDxbdSFF9aWoaCVGDfbP1tcp-aTMmydqZLnkX5DAGQPDawsiuXuWuwvUDPz6f4K5F78r4D8ldl8cCSO0uniSv3mIZYbgDuzwfjIrV_lN5pFYHg38f-7RcwvE-TARr0wJ1dNcM9XnNTJRXxsJRpJP-LAG369smEnRk2Z2D7Gds0KCAK7zKcwRyJh8u7_YCLcMVJR97mhJk-n4zEfnD3yxa0VsiNHkHiAAjtXF78ASWBW2LXXYlvn0Mu0tcltZ7Qur9-TslHjUhD1BmNkQzwTkQte3kbMk7HsCDZCWaxr-j_8ApD 
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 
DNT: 1 
Referer: http://localhost:42458/ 
Accept-Encoding: gzip, deflate, br 
Accept-Language: en-US,en;q=0.8 

これは失敗したアプリケーション内の角度コードです:私の工場で

var deferred = $q.defer(); 
$http({ 
    method: 'POST', 
    url: logoutUrl, 
    headers: { 
     'Authorization': 'Bearer ' + accessToken 
     ,'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' 
    }, 
}).then(function (data, status, headers, cfg) { 
    accessToken = null; 
    deferred.resolve({ status: 'success' }); 
}, function (err, status) { 
    console.log(err); 
    deferred.reject(status); 
}); 
return deferred.promise; 

ここで経由する生のHTTPリクエストです。 OPTIONSプリフライトチェックはここで失敗し、POSTは実行されません。

OPTIONS http://localhost:56508/api/Account/Logout HTTP/1.1 
Host: localhost:56508 
Connection: keep-alive 
Access-Control-Request-Method: POST 
Origin: http://localhost:45743 
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 
Access-Control-Request-Headers: authorization 
Accept: */* 
DNT: 1 
Referer: http://localhost:45743/ 
Accept-Encoding: gzip, deflate, br 
Accept-Language: en-US,en;q=0.8 
+0

プリフライトは同じように見えますが、正常に動作するはずです。両方のクライアントが同じサービスを呼びますか? – zameb

+0

はい、両方とも同じサービスを呼び出しています。 – KrimblKrum

答えて

0

問題は私の$ httpリクエストまたはCORSではないことが分かりました。この問題は、非同期関数が同期しているかのように呼び出され、要求が完了する前にキャンセルされたために発生しました。

以下は、記述が不適切だったコードの例です。ログアウト機能は、$ http要求をカプセル化します。

authService.logout(); 
    $window.location.href = location.origin; 

以下は、コードの例です。このコードは期待どおりに動作します。

authService.logout().then(function success(data){ 
     $window.location.href = location.origin; 
    }, function failure(data) { 
     $window.location.href = location.origin; 
    }); 

解決する約束を待つことなく、$ httpがエラーコールバックを実行するが、エラーオブジェクトは利用できません。したがって、実際にPOSTがクライアントによって途中でキャンセルされたときにプリフライトが失敗したと考えました。

関連する問題