Angular2アプリケーションを開発しています。私のアクセストークンが期限切れになると、Responseオブジェクトで401 HTTPステータスコードが値0に変更されるようです。 401 Unauthorizedを受け取っていますが、ERROR Responseオブジェクトのステータスは0です。これにより、401エラーをトラップしてトークンの更新を試みることができません。 401 HTTPステータスコードが0のHTTPステータスコードに変更される原因は何ですか?
Firefoxのコンソールのスクリーンショットは次のとおりです。
私のコードは次のとおりです。
get(url: string, options?: RequestOptionsArgs): Observable<any>
{
//console.log('GET REQUEST...', url);
return super.get(url, options)
.catch((err: Response): any =>
{
console.log('************* ERROR Response', err);
if (err.status === 400 || err.status === 422)
{
return Observable.throw(err);
}
//NOT AUTHENTICATED
else if (err.status === 401)
{
this.authConfig.DeleteToken();
return Observable.throw(err);
}
else
{
// this.errorService.notifyError(err);
// return Observable.empty();
return Observable.throw(err);
}
})
// .retryWhen(error => error.delay(500))
// .timeout(2000, new Error('delay exceeded'))
.finally(() =>
{
//console.log('After the request...');
});
}
このコードは、Angular2のHTTPを拡張するカスタムHTTPサービスに存在するため、1つの場所でエラーをインターセプトできます。
Google Chromeでは、次のエラーメッセージが表示されます。
XMLHttpRequestを読み込むことができません https://api.cloudcms.com/repositories/XXXXXXXXXXXXXXXXXXX/branches/XXXXXXXXXXXXXXXX/nodesXXXXXXXXXXXXXXXX 。要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。 Origin ' http://screwtopmedia.local.solutiaconsulting.com 'はアクセスを許可されていません。応答のHTTPステータスコード401。
要求に「Access-Control-Allow-Origin」ヘッダーが含まれているため、これは混乱を招きます。
Google Chromeで受信した結果の写真は次のとおりです。
401をトラップする手段として「WWW-Authenticate」応答ヘッダーにアクセスしようとしました。ただし、次のコードはNULLを返します。
err.headers.get("WWW-Authenticate")
有効なアクセストークンが提供されたときにCORSエラーが表示されないため、CORSの問題が発生しているのは不可解です。
401 HTTPステータスコードをトラップするにはどうすればよいですか? 401 HTTPステータスコードが0に変更されるのはなぜですか?
ご協力いただきありがとうございます。
私はCloud CMSで働いています。 API呼び出しでCORSヘッダーが適切に設定されていることを確認できます。ただし、401応答の場合、ヘッダーは適切に設定されません。これは解決されており、修正は今週の終わりに公開APIで利用可能になります。
ところで、JavaScriptドライバーを使用する場合 https://github.com/gitana/gitana-javascript-driver APIに直接書き込む代わりに、再認証フローが自動的に処理されるため、不要です401エラーをトラップします。
この問題はCORSリクエストに関連しています。 このgithubの問題 を参照してください
要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません
は、'Access-Control-Allow-Origin'
が応答ヘッダーに必要であることを意味します。
Angularはステータスコードを取得していないため、ブラウザは0
がresponse
を無効にしてheaders
を解析できないため、xml parser
を取得します。
正しい[CORS headersをerror response
およびsuccess
に追加する必要があります。
Cloudcms.comが401応答でAccess-Control-Allow-Origin
を設定しない場合、何もできません。適切にサポートチケットを開いて、それが正常な動作であるかどうかを確認する必要があります。
ブラウザのjavascript(FF、Chrome&Safari)CORSエラーが発生した場合、ステータス0以外はテストされません。Angular2はそれを制御しません。
私は簡単なテストを作成し、あなたと同じ結果を得ました:
geturl() {
console.log('geturl() clicked');
let headers = new Headers({ 'Content-Type': 'application/xhtml+xml' });
let options = new RequestOptions({ 'headers': headers });
this.http.get(this.url)
.catch((error): any => {
console.log('************* ERROR Response', error);
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Web Server error';
return Observable.throw(error);
})
.subscribe(
(i: Response) => { console.log(i); },
(e: any) => { console.log(e); }
);
}
多くのグーグルの後、私は次を見つけました( https://github.com/angular/angular.js/issues/3336 ):
lucasspは2013年8月19日にコメントしました
私はしばらくの間この問題を見つけましたが、返信をここに投稿するのを忘れました。エラー500を含むすべての応答には、CORSヘッダーが添付されている必要があります。サーバーがCORSヘッダーをエラー500応答に添付しない場合、XHRオブジェクトはそれを解析しないため、XHRオブジェクトは応答本体、ステータス、またはその他の応答データを内部に持ちません。
Firefoxネットワークモニターの結果は、上記の理由をサポートしているようです。
JavaScriptリクエストは空のレスポンスを受け取ります。
プレーンなURLリクエスト(アドレスバーにリンクをコピーして貼り付ける)は、応答本文を取得します
Javascriptは、http通信にXHRHttpRequestを使用します。
XHR応答が到着すると、ブラウザがヘッダーを処理するため、これらの401ネットワークメッセージが表示されます。ただし、XHR応答が別のホストから送信された場合、javascriptおよび応答ヘッダーにCORSヘッダーが含まれていない場合(例:Access-Control-Allow-Origin: *
)、ブラウザーはXHRレイヤーに情報を返しません。その結果、応答本文はstatus(0)なしで完全に空になります。
FF 48.0.1、Chrome 52.0.2743.116およびSafari 9.1.2でテストしましたが、すべて同じ動作をします。
ブラウザネットワークモニターを使用して、これらの401 Unauthorized
エントリの応答ヘッダーを確認します。Access-Control-Allow-Origin
ヘッダーがなく、直面している問題の原因である可能性が非常に高いです。これはバグであるか、サービスプロバイダー側の設計によるものです。
Access-Control-Allow-Origin
は、応答専用のhttpヘッダーです。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#The_HTTP_response_headers の詳細について
W3C によると、ステータス属性が0に設定されている場合、次のことを意味します。
または
これはAngular2
の問題ではなく、リクエストに問題があるようです。
Chrome devツールではなく、サードパーティのHTTPプロトコルモニター(CharlesProxyなど)を使用して、APIサービスに実際に送信されているヘッダーと401を返すかどうかを確認する必要があります。
同じ問題が発生し、サーバーが正しい応答を送信しなかったことが原因でした(コンソールログにAngularエラーのステータスが0と表示されていた場合でも)。私のサーバーは、Spring MVCとSpring Securityを使用したJavaアプリケーションを備えたTomcatでした。
現在、次のセットアップを使用して動作しています。
SecurityConfig.Java
...
protected void configure(HttpSecurity http) throws Exception {
....
http.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint);
// allow CORS option calls
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
...
SomeAuthenticationEntryPoint.Java
@Component
public class SomeAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
HttpStatus responseStatus = HttpStatus.UNAUTHORIZED;
response.sendError(responseStatus.value(), responseStatus.getReasonPhrase());
}
}
web.xml
<error-page>
<error-code>403</error-code>
<location>/errors/unauthorised</location>
</error-page>
<error-page>
<error-code>401</error-code>
<location>/errors/unauthorised</location>
</error-page>
以前に定義された/ errors/...を処理するコントローラー
@RestController
@RequestMapping("/errors")
public class SecurityExceptionController {
@RequestMapping("forbidden")
public void resourceNotFound() throws Exception {
// Intentionally empty
}
@RequestMapping("unauthorised")
public void unAuthorised() throws Exception {
// Intentionally empty
}
}
}
このアイテムにつまずいた:
私の場合に起こることはそれでした:
cORSが許可されていなかったため(「Access-Control-Allow-Origin」ヘッダーがない)-Chromeはこの応答をAngularに渡すことができませんでした。このようにChromeが、Angularではありません。
解決策は簡単でした(TimothyBrakeの答えを拡張)-欠落しているヘッダーをエラー応答に追加します。 Springブートではresponse.addHeader("Access-Control-Allow-Origin", "*");
と入力し、整理されました。
@Component public class JwtUnauthorizedResponseAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { response.addHeader("Access-Control-Allow-Origin", "*"); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "You would need to provide the Jwt Token to Access This resource"); } }
PS:BeanがWebSecurityConfigurerAdapterのHttpSecurity configに提供されていることを確認してください。参照: https://www.baeldung.com/spring-security-basic-authentication 疑わしい場合.
お役に立てれば。