2017-12-22 25 views
2

を使用して2つのJS私はこのようなvuexストアの成功のログインコールの後にトークンを格納します。Axiosインターセプターvuex

axios.post('/api/auth/doLogin.php', params, axiosConfig) 
    .then(res => { 
     console.log(res.data); // token 
     this.$store.commit('login', res.data); 
    }) 

axiosConfigは、私が唯一のbaseURL export default { baseURL: 'http://localhost/obiezaca/v2' }とのparamsを設定ファイルであるバックエンドに送信されたデータだけです。私vuexファイルが見えます

がある:それは正常に動作している

import Vue from 'vue'; 
import Vuex from 'vuex'; 

Vue.use(Vuex); 

export const store = new Vuex.Store({ 
    state: { 
     logged: false, 
     token: '' 
    }, 
    mutations: { 
     login: (state, response) => { 
      state.logged = true; 
      state.token = response; 
      console.log('state updated'); 
      console.log('state.logged flag is: '+state.logged); 
      console.log('state.token: '+state.token); 
     }, 
     logout: (state) => { 
      state.logged = false; 
      state.token = ''; 
     } 
    } 
}); 

、私がログインしているユーザーのためのv-if="this.$store.state.logged"の私のSPAの基点にコンテンツの一部を再レンダリングすることができます。私はアプリ全体の任意のコンポーネントからthis.$store.state.loggedにアクセスできます。

今、残りのAPIバックエンドを呼び出すすべてのリクエストにトークンを追加します。

import axios from 'axios'; 

axios.interceptors.request.use(function(config) { 
    const token = this.$store.state.token; 
    if(token) { 
     config.headers.Authorization = `Bearer ${token}`; 
    } 
    return config; 
}, function(err) { 
    return Promise.reject(err); 
}); 

私は基本的なAxios httpインターセプタを作成しました。

  1. は、私はすべてのコンポーネント間でthis.$store.state.loggedまたはthis.$store.state.tokenを使用して利用可能であることを知っているが、私はそれを単一のJavaScriptファイルにも同じように使うことができますか?
  2. インターセプタのjavascriptファイルはどこで実行する必要がありますか?それは私のアプリのメインフォルダにある独立したファイルですが、私は前に働いていたangularJSのどこでも呼び出すわけではありません。私は$httpProvider.interceptors.push('authInterceptorService');を設定に追加しなければなりませんでしたが、vueアーキテクチャで同じことをする方法はわかりません。だからどこでインターセプターを注入すべきですか?

EDIT

は、私は私のmain.jsファイルに

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

を追加GMaioloヒントに続いて、私はこれに私のインターセプタをリファクタリング:

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

export default function execute() { 
    axios.interceptors.request.use(function(config) { 
     const token = this.$store.state.token; 
     if(token) { 
      config.headers.Authorization = `Bearer ${token}`; 
     } 
     return config; 
    }, function(err) { 
     return Promise.reject(err); 
    }); 
} 

結果この変更の中には、既に存在するすべてのバックエンドcトークンを必要としないalls(GET)は動作を停止しましたが、どの要求にトークンを追加すべきかを明確にしなかったので論理的です。どこにでも追加しようとしています。なぜ既に存在していた要求がすべて機能しなくなったのか

私は、ブラウザのコンソールで、バックエンドのPOST呼び出しをしようとすると、私はまだ、このエラーを取得:私は私のインターセプタファイルにストアをインポートしますが

TypeError: Cannot read property '$store' of undefined

を。何か案は?必要に応じてさらに情報を提供することができます。

path

答えて

2

1:あなたは私はフロン正しいパスをインポートしてることを見ることができるように

は、私はさらに、このメイン、店舗や迎撃ツリー構造のスクリーンショットを追加します。

まず、Vuex Moduleを使用します。このログイン/セッションの動作は、Sessionモジュールには理想的です。あなたはVuex外からstate自体へのアクセスを避けるためにGetterを設定することができます(これは完全に任意である)その後、あなたはこのようなものに終わるだろうと思います。これらのゲッターがセットされると

state: { 
    // bear in mind i'm not using a module here for the sake of simplicity 
    session: { 
    logged: false, 
    token: '' 
    } 
}, 
getters: { 
    // could use only this getter and use it for both token and logged 
    session: state => state.session, 
    // or could have both getters separated 
    logged: state => state.session.logged, 
    token: state => state.session.token 
}, 
mutations: { 
    ... 
} 

、あなたが得ることができます値はコンポーネントから少し簡単です。 this.$store.getters.logged(または使用したいと思います1)を使用したりVuexからmapGettersヘルパーを使用してのいずれかで、[このについての詳細は、あなたはゲッタードキュメントをチェックすることができます]:

import { mapGetters } from 'vuex' 
export default { 
    // ... 
    computed: { 
    ...mapGetters([ 
     'logged', 
     'token' 
    ]) 
    } 
} 

2.

私はmain.jsのVueインスタンシエーションと一緒にAxiosのインターセプタを実行して、interceptors.jsヘルパーを作成、インポート、実行するのが好きです。私は再び、これは私自身の好みです、あなたがアイデアを得るための例を残して、しかしでしょう:

main.js

import Vue from 'vue'; 
import store from 'Src/store'; 
import router from 'Src/router'; 
import App from 'Src/App'; 

// importing the helper 
import interceptorsSetup from 'Src/helpers/interceptors' 

// and running it somewhere here 
interceptorsSetup() 

/* eslint-disable no-new */ 
new Vue({ 
    el: '#app', 
    router, 
    store, 
    template: '<App/>', 
    components: { App } 
}); 

interceptors.js

import axios from 'axios'; 
import store from 'your/store/path/store' 

export default function setup() { 
    axios.interceptors.request.use(function(config) { 
     const token = store.state.token; 
     if(token) { 
      config.headers.Authorization = `Bearer ${token}`; 
     } 
     return config; 
    }, function(err) { 
     return Promise.reject(err); 
    }); 
} 

これで、すべての動作がきれいにカプセル化されることになります。

+0

トークンcostantを宣言した行で、このエラーが発生します。 'TypeError:プロパティ '$ store'がeval(httpInterceptor.js?c694:5)で未定義の'を読み込めません。私はGetterを使ってそれを集めるのではなく、 'this。$ store.state.token; 'でこれを達成しようとしました。私はそこにvuexをインポートする必要がありますか?または、このゲッターをこの場合に使用する必要がありますか? – BT101

+0

'this。$ store.state.token'は私のインターセプタでは利用できません。 – BT101

+0

はい! 'interceptors.js'の中からストアをインポートする必要があります。 – GMaiolo

関連する問題