次のように、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バックエンドを呼び出すすべてのリクエストにトークンを追加します。次のような基本的なaxios httpインターセプターを作成しました。
_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);
});
_
現在、2つの問題/質問があります。
this.$store.state.logged
_または_this.$store.state.token
_を使用できることを知っていますが、単一のJavaScriptファイルで同じように使用できますか?$httpProvider.interceptors.Push('authInterceptorService');
を追加する必要がありましたが、同じ方法はわかりませんvue architecture。では、インターセプターをどこにインジェクトする必要がありますか?[〜#〜] edit [〜#〜]
追加したGMaioloヒントを追加しました
_import interceptor from './helpers/httpInterceptor.js';
interceptor();
_
main.jsファイルに追加し、インターセプターをこれにリファクタリングします。
_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);
});
}
_
この変更の結果、動作するためにトークンを必要としない既存のすべてのバックエンドコール(GET)は動作を停止しましたが、どのリクエストにトークンを追加する必要があるかを明確にしていないため、どこにでも追加しようとしています私のインターセプターでは何かがまだ間違っているため、すでに存在するすべてのリクエストが機能しなくなったのです。
バックエンドを実行しようとすると、POSTブラウザコンソールで呼び出しますが、このエラーが表示されます。
TypeError:未定義のプロパティ「$ store」を読み取ることができません
ストアをインターセプターファイルにインポートしますが。何か案は?必要に応じて、さらに情報を提供できます。
さらに、このメイン、ストア、インターセプターのツリー構造のスクリーンショットを追加して、正しいパスをインポートしていることを確認できるようにします。
まず、 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
(または使用するもの)を使用するか、VuexのmapGetters
ヘルパーを使用します[これについての詳細は、getters docsを確認してください。 ]:
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
...mapGetters([
'logged',
'token'
])
}
}
私はAxiosのインターセプターをVue main.js
のインスタンス化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.getters.token;
if(token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}, function(err) {
return Promise.reject(err);
});
}
そして、すべての動作がきれいにカプセル化されることになります。