🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CORS

CORSとはCross-Origin Resource Sharingの頭文字をとったもので、ブラウザがオリジン以外のサーバからデータを取得するシステムのことです。

Q&A

解決済

3回答

20186閲覧

XMLHttpRequestでBasic認証の付いているサーバーに対しapiを叩く

zushi0905

総合スコア683

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CORS

CORSとはCross-Origin Resource Sharingの頭文字をとったもので、ブラウザがオリジン以外のサーバからデータを取得するシステムのことです。

0グッド

7クリップ

投稿2019/10/23 04:09

編集2019/10/23 05:43

laravelで作成したapiをjsのXMLHttpRequestを使って叩こうとしています。
サーバー側とクライアント側は違うサーバーで運用しており、共にbasin認証がかけてあります。

サーバー側

laravelを使って作成しています。 Corsの許可をおこなっているmiddlewareは以下です。

php

1// middleware/Cors.php 2 public function handle($request, Closure $next) 3 { 4 return $next($request) 5 ->header('Access-Control-Allow-Origin','*') 6 ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') 7 ->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Requested-With') 8 ->header('Access-Control-Allow-Credentials', 'true'); 9 }

クライアント側

jsのXMLHttpRequestを使って叩いています。

js

1 var request = new XMLHttpRequest(); 2 // URLを開く 3 request.open('GET', url , [true,clientId,clientSecret]); 4 request.responseType = 'json'; 5 6 // レスポンスが返ってきた時の処理を記述 7 request.onload = function () { 8 // レスポンスが返ってきた時の処理 9 //省略 10 } 11 // リクエストをURLに送信 12 request.send();

エラー内容

error

1index.php:1864 GET http://サーバーurl 401 (Unauthorized) 2 (anonymous) @ index.php:1864 3 mightThrow @ jquery-3.4.1.js:3557 4 process @ jquery-3.4.1.js:3625 5 setTimeout (async) 6 (anonymous) @ jquery-3.4.1.js:3663 7 fire @ jquery-3.4.1.js:3291 8 fireWith @ jquery-3.4.1.js:3421 9 fire @ jquery-3.4.1.js:3429 10 fire @ jquery-3.4.1.js:3291 11 fireWith @ jquery-3.4.1.js:3421 12 ready @ jquery-3.4.1.js:3901 13 completed @ jquery-3.4.1.js:3911 14index.php:1 Access to XMLHttpRequest at 'http://サーバーurl' from origin 'サーバーurl' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

やってみたこと

  • setRequestHeaderを使ってbasin認証の情報を付与する。

js

1var authorizationBasic = window.btoa(clientId + ':' + clientSecret); 2 3request.open('GET', 'url', true); 4request.responseType = 'json'; 5request.setRequestHeader('Authorization', 'Basic ' + authorizationBasic);
  • Postmanから叩いた場合はデータが取れます。この事からサーバー側の問題ではないのではないかと考えています。

  • 開発時にlocalhostで実装した際には動いており、サーバーに乗せたときに動かなくなった為、basic認証周りではないのかと考えていますが、いくつかのXMLHttpRequestにbasic認証情報を与える試しましたが反応がなく困っております。

問題の本質が見切れていない状態ですが困ってしまいました。何か気になる方でも構いません。回答よろしくお願い致します。

解決方法

withCredentialsプロパティをtrueに設定する。
この際にサーバー側の'Access-Control-Allow-Origin'の設定がワイルドカード(*)になっているとエラーが発生するので、クライアント側のドメイン指定のみにしてあげる必要がありました。

js

1// URLを開く 2 request.open('GET', url, [true, clientId, clientSecret]); 3 request.responseType = 'json'; 4 request.withCredentials = true;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

直接の原因は、withCredentialsプロパティをtrueにしていないことだと思います。プリフライトを回避するには、「やってみたこと」の方法ではだめで、もとの方法なら大丈夫です。
また、BASIC認証を伴うCORSについては以下のQ&Aも参考になると思います。

BASIC認証をかいくぐってCORSしたい|teratail

投稿2019/10/23 04:46

ockeghem

総合スコア11705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zushi0905

2019/10/23 05:39

withCredentialsプロパティを追加したところ無事動きました。 リンク先の情報もとても参考になりました、ありがとうございます。
guest

0

jsでbasic認証突破するということは生のユーザー名とパスワードを
さらすということですから別の意味でセキュリティ上問題があります。
運用方法を検討しなおしたほうがよいと思います。

※ユーザー名パスワードを手動で入力するUIを想定しているのでしたら
的はずれな回答になりますのでスルーしてください

投稿2019/10/23 04:52

編集2019/10/23 04:54
yambejp

総合スコア116663

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zushi0905

2019/10/23 05:46

こちらは最終的にはbasic認証を外す予定でして、今現在の段階ではクライアント、サーバー共にbasic認証をかけて運用している為大丈夫と考えています。 実際に運用する際に残さないように気をつけます。アドバイスありがとうございます。
guest

0

Authorization:など、特別なヘッダを付けてクロスドメインのリクエストを行う場合、

  1. OPTIONSによって、そのヘッダを受け入れられるかを問い合わせるプリフライトリクエストが飛ぶ
  2. 1の結果で受け入れられるとなれば、本来のリクエストを投げる

という流れで進みます(MDN)。ということで、Authorization:を使うBasic認証などをクロスドメインで通すには、OPTIONSBasic認証なしで応答できる必要があります。多くの環境では、現実的に実装が難しいかもしれません。

投稿2019/10/23 04:28

編集2019/10/23 04:31
maisumakun

総合スコア145970

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zushi0905

2019/10/23 05:46

徳丸先生の回答にて解決することが出来ました。回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問