Programing

vuex를 이용한 vue 2 JS에서의 Axios 요격

c10106 2022. 3. 12. 10:16
반응형

vuex를 이용한 vue 2 JS에서의 Axios 요격

로그인 호출 성공 후 다음과 같이 vuex 저장소에 토큰을 저장한다.

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

axiosConfig는 기본만 설정하는 파일이다.URLexport default { baseURL: 'http://localhost/obiezaca/v2' }그리고 매개 변수는 백엔드로 전송되는 데이터일 뿐이다.

내 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 = '';
        }
    }
});

제대로 작동하고 있어, 내 SPA에서 콘텐츠를 리렌더할 수 있어.v-if="this.$store.state.logged"로그 사용자용.접속이 가능하다.this.$store.state.logged내 앱의 모든 컴포넌트에서.

이제 나머지 API 백엔드를 호출하는 모든 요청에 내 토큰을 추가하고 싶다.나는 다음과 같은 기본적인 공리 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);
});

이제 나는 그것에 대해 두 가지 문제/질문을 가지고 있다.

  1. 사용 가능한 것으로 알고 있다.this.$store.state.logged또는this.$store.state.token모든 컴포넌트에 걸쳐 있지만, 단일 자바스크립트 파일에 동일한 방식으로 사용할 수 있는가?
  2. 인터셉터 자바스크립트 파일을 실행/시작하는 위치그것은 내 앱 메인 폴더에 있는 독립 파일이지만 나는 그것을 어디에서도, 각도로 부르지 않는다.내가 전에 일하던 JS, 나는 추가해야 했다.$httpProvider.interceptors.push('authInterceptorService');구성에서 그러나 나는 vue 건축에서 어떻게 같은 일을 하는지 모른다.그렇다면 내 요격기를 어디에 주사해야 할까?

편집

나는 내가 추가한 지마이로 팁을 따라갔다.

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 )은 작동을 멈췄지만, 어떤 요청을 추가해야 하는지를 명확히 하지 않았기 때문에 논리적이고, 그래서 나는 어디에나 토큰을 추가하려고 시도하고 있고, 그래서 이미 존재하는 모든 요청이 작동을 멈췄다.g

브라우저 콘솔에서 백엔드 POST 호출을 시도해도 다음 오류가 표시됨:

TypeError: 정의되지 않은 속성 '$store'를 읽을 수 없음

저장소를 인터셉터 파일로 가져오지만좋은 생각 있어?필요한 것이 있으면 더 많은 정보를 제공할 수 있다.

이 메인, 스토어 및 인터셉터 트리 구조의 스크린샷을 추가하여 올바른 경로를 가져오는 것을 확인할 수 있도록 추가:

경로

1.

먼저 Vuex 모듈을 사용하십시오. 이 로그인/세션 동작은Session모듈그 후(완전히 선택 사항) Getter를 설정하여 액세스하지 않도록 할 수 있다.state브룩스 외곽에서 왔으면 이런 일이 벌어졌을 겁니다

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(또는 사용하고자 하는 제품) 또는 사용 방법mapGettersVuex의 도우미 [이 문제에 대한 자세한 내용은 Getter 문서를 확인하십시오]:

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

2.

나는 악시오스의 가로채기와 부에 인스턴스화를 함께 실행하는 것을 좋아한다.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 }
});

요격기.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);
    });
}

그리고 거기서 모든 행동을 깨끗하게 봉합하게 될 것이다.

나도 같은 논리를 폈다.하지만 나는 파일 이름만 바꾼다.axios/index.js를 사용했지만 스토어가 정의되어 있지 않아 파일 이름 axios/interceptor.js만 변경하면 아래 이미지를 통해 저장소 데이터에 액세스할 수 있는지 알 수 없음

참조URL: https://stackoverflow.com/questions/47946680/axios-interceptor-in-vue-2-js-using-vuex

반응형