Аутентификация Vuex + Axios неправильный статус запроса URL 404 - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь аутентифицироваться с помощью API, который я использую, но когда я пытаюсь войти в систему, я получаю этот ответ: «Не удалось загрузить ресурс: сервер ответил со статусом 404 (не найден) [http://localhost:8080/localhost:5000/api/login]"

Я думаю, что проблема в axios, потому что он использует мой локальный адрес приложения Vue + apiAdress для выполнения запроса.

main.js:

import axios from 'axios'
Vue.use(axios)
axios.defaults.baseURL = process.env.VUE_APP_API; //(http://localhost:5000/api

модули / auth.js:

import { AUTH_REQUEST, AUTH_ERROR, AUTH_SUCCESS, AUTH_LOGOUT } from '../actions/auth'
import { USER_REQUEST } from '../actions/user'
import axios from 'axios'

const state = { token: localStorage.getItem('user-token') || '', status: '', hasLoadedOnce: false }

const getters = {
  isAuthenticated: state => !!state.token,
  authStatus: state => state.status,
}

const actions = {
  [AUTH_REQUEST]: ({commit, dispatch}, user) => {
    return new Promise((resolve, reject) => {
     commit(AUTH_REQUEST)
  axios({url: '/login', data: user, method: 'POST'})
  .then(resp => {
    localStorage.setItem('user-token', resp.token)
    // Here set the header of your ajax library to the token value.
    axios.defaults.headers.common['Authorization'] = resp.token
    commit(AUTH_SUCCESS, resp)
    dispatch(USER_REQUEST)
    resolve(resp)
  })
  .catch(err => {
    commit(AUTH_ERROR, err)
    localStorage.removeItem('user-token')
    reject(err)
  })
})
},
}

const mutations = {
  [AUTH_REQUEST]: (state) => {
  state.status = 'loading'
  },
  [AUTH_SUCCESS]: (state, resp) => {
    state.status = 'success'
    state.token = resp.token
    state.hasLoadedOnce = true
  },
  [AUTH_ERROR]: (state) => {
  state.status = 'error'
  state.hasLoadedOnce = true
  },
  [AUTH_LOGOUT]: (state) => {
    state.token = ''
  }
}

export default {
 state,
 getters,
 actions,
 mutations,
}

Login.vue:

  methods: {
    login() {
      const { username, password } = this
      this.$store.dispatch(AUTH_REQUEST, { username, password }).then(() => {
      this.$router.push('/')
   })
    },

1 Ответ

0 голосов
/ 24 января 2019

Вам вообще не нужно определять axios в main.

Кроме того, axios не является плагином vue, поэтому Vue.use(axios) ничего не делает.

в вашем auth.js выможно создать экземпляр

const axios = require('axios');

const axiosInstance = axios.create({
  baseURL: process.env.VUE_APP_API
});

и в своих действиях использовать экземпляр axios вместо axios

const actions = {
  [AUTH_REQUEST]: ({commit, dispatch}, user) => {
    return new Promise((resolve, reject) => {
     commit(AUTH_REQUEST)
  axiosInstance({url: '/login', data: user, method: 'POST'})
  .then(resp => {
    localStorage.setItem('user-token', resp.token)
    // Here set the header of your ajax library to the token value.
    axios.defaults.headers.common['Authorization'] = resp.token
    commit(AUTH_SUCCESS, resp)
    dispatch(USER_REQUEST)
    resolve(resp)
  })
  .catch(err => {
    commit(AUTH_ERROR, err)
    localStorage.removeItem('user-token')
    reject(err)
  })
})

Однако это может вызвать проблемы с обновлением заголовков после создания экземпляра, поэтомувам может понадобиться использовать несколько хитрых способов обойти это.

Один из способов - использовать функцию вместо значения, чтобы при каждом вызове она использовала данные в вашем локальном хранилище

const axiosInstance = axios.create({
  baseURL: process.env.VUE_APP_API,
  headers: {
    Authorization: {
      toString () {
        return `Bearer ${localStorage.getItem('user-token')}`
      }
    }
  }
})

другой способ - создавать новый запрос каждый раз, когда вы совершаете звонок

const actions = {
  [AUTH_REQUEST]: ({ commit, dispatch }, user) => {
    return new Promise((resolve, reject) => {
      const axiosInstance = axios.create({
        baseURL: process.env.VUE_APP_API
      });
      commit(AUTH_REQUEST)
      axiosInstance({
          url: '/login',
          data: user,
          method: 'POST'
        })
        .then(resp => {
          localStorage.setItem('user-token', resp.token)
          // Here set the header of your ajax library to the token value.
          axios.defaults.headers.common['Authorization'] = resp.token
          commit(AUTH_SUCCESS, resp)
          dispatch(USER_REQUEST)
          resolve(resp)
        })
        .catch(err => {
          commit(AUTH_ERROR, err)
          localStorage.removeItem('user-token')
          reject(err)
        })
    })
  },
  [SECURE_REQUEST]: ({ commit, dispatch }, user) => {
    return new Promise((resolve, reject) => {
      const axiosInstance = axios.create({
        baseURL: process.env.VUE_APP_API,
        headers: {
          'Authorization': 'Bearer ' + localStorage.getItem('user-token')
        }
      });
      commit(SECURE_REQUEST)
      axiosInstance({
          url: '/getData',
          data: user,
          method: 'POST'
        })
        // ...
    })
  },
}

другой вариант (который я использую в эти дни) - использовать конфигурацию devServer.proxy.Это требует, однако, что вы используете Vue-Cli-3.Также предполагается, что окончательный статический пакет будет работать на том же сервере, что и ваш API, что может не сработать для вас.

также проверьте это решение: https://github.com/axios/axios/issues/1383#issuecomment-405900504

...