web-dev-qa-db-ja.com

Axiosインターセプタートークンヘッダーは構成に存在しますが、要求ヘッダーには存在しません

すべてのリクエストがRESTAPIに送信される前にトークンを追加する責任があるaxiosインターセプターを作成しました。

import axios from 'axios';
import { store } from '../store/store';

export default function execute() {
    axios.interceptors.request.use(function(config) {
        const token = store.state.token;
        if(token) {
            config.headers.Authorization = `Bearer ${token}`;
            console.log(config);
            return config;
        } else {
            console.log('There is not token yet...');
            return config;
        }
    }, function(err) {
        return Promise.reject(err);
    });
}

2行目でわかるように、私はvuexストレージをインポートしています。これは、実際にはトークンが保管される場所です。 8行目では、実際にこのトークンをconfigオブジェクトに追加しており、次の行ではそれを慰めています。

それは次のように私のmain.jsファイルで実行されます:

import interceptor from './helpers/httpInterceptor.js';
interceptor();

トークンは、コンソールに表示されるconfigオブジェクトに存在します(コンソールにconfigオブジェクトがあるため)。

img

期待どおりにAPIを停止するように要求するたびに実行されます。トークンが存在する場合(ログイン後)、すべてのリクエストにトークンヘッダーを追加する必要があります。残念ながら、それはconfigオブジェクトに存在しますが、それを追加しないので、少し混乱します。

ネットワークタブに表示されているように、実際には実際のリクエストにトークンは追加されません。

imgd

このスクリーンショットはもちろんログイン後に撮影されたものなので、トークンはすでにvuexストレージにあり、ログアウト関数(REST APIを呼び出す)を実行した後、config(インターセプターの一部)をコンソールアウトしました。

その結果、トークンを送信しなかったため、REST APIからの応答で400(不正なリクエスト)ステータスになりました。

編集!!!

私はそれをより良くするためにこの質問に何を追加できるかを考えていました。これはデモプランカーを作成することは不可能だと思うので、ダウンロードして問題を確認できる小さな リポジトリ デモを作成することにしました。それが問題の解決に役立つことを願っています!

11
dopeCode

わかりました。

APIを休止する実際のリクエストの前に実行されるプリフライトリクエストと呼ばれるものがあることを知りませんでした。プリフライトリクエストが失敗した場合、それ以上のヘッダーを受け入れたり受信したりしません。これが、実際のリクエストでchromeコンソールネットワークタブに表示されなかったが、インターセプターでconsole.logされた構成オブジェクトにあった理由です。

既存のURLを呼び出さなかったリポジトリデモでも同じであるため、プリフライトリクエストもそこで失敗しました。このデモを作成している間、プリフライトリクエストなどが存在することを知らなかったので、既存のURLエンドポイントを呼び出すか、架空のエンドポイントを呼び出すかは問題ではないと確信していました。どちらの方法でも表示できるはずだと思いました。そこにヘッダーを要求します。

4
dopeCode

期限切れになったときに、クリーンアップトークンへの応答を操作することもできます。

  axios.interceptors.response.use(function (response) {
    return response;
  }, function (error) {
    if (401 === error.response.status) {
      console.log("Session Expired")
      //window.location = '/login'
    } else {
      return Promise.reject(error);
    }
  });