Запрос не выполняется после получения токена JWT - PullRequest
0 голосов
/ 02 февраля 2019

Я использую Django JWT с DRF и Vue Js с axios.Когда пользователь входит в систему, я получаю и сохраняю токен в локальном хранилище, которое, как я подтвердил, работает.Затем я перенаправляю на новую страницу, где делаю еще один запрос на получение данных.Каждый раз, когда я перенаправляю на эту страницу, я получаю 401 не авторизованный, и когда я обновляю страницу, она работает нормально.Я проверил, чтобы убедиться, что токен хранится перед тем, как сделать второй запрос.Я пытаюсь получить данные на перенаправленной странице в созданном хуке.Я также создаю экземпляр axios для работы с заголовками и использования базового маршрута, а затем импортирую его в файлы, где это необходимо, я не уверен, что это как-то связано с ним.Это также происходит только тогда, когда срок действия токена истек, и вы пытаетесь получить новый.Стоит ли обновлять токен вместо того, чтобы пытаться получить новый?

Экземпляр Axios

import axios from 'axios'

export default axios.create({
  baseURL: `http://127.0.0.1:8000/`,
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'JWT ' + localStorage.getItem('token')
  },
  xsrfCookieName: 'csrftoken',
  xsrfHeaderName: 'X-CSRFToken',
  withCredentials: true
})

Редактировать

api.js

import axios from 'axios'

export default axios.create({
  baseURL: `http://127.0.0.1:8000/`,
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'JWT ' + localStorage.getItem('token')
  },
  xsrfCookieName: 'csrftoken',
  xsrfHeaderName: 'X-CSRFToken',
  withCredentials: true
})

AppLogin.vue

Подтверждение инициируется нажатием кнопки входа в систему

 confirm: function() {
       API.post("accounts/login/", {
        email: this.email,
        password: this.password,
       })
        .then(result => {
          console.log(result.data.token);
          this.token = result.data.token;
          localStorage.setItem("token", this.token);
          this.getUserInfo()
        })
        .catch(error => {
          console.log(error);
        });

    },
    getUserInfo: function(){
      axios.get("http://127.0.0.1:8000/userinfo/get/", {
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'JWT ' + this.token
        }
      })
        .then(response => {
          console.log(response.data.pos);
          var pos = response.data.pos;
          this.reroute(pos);
        })
        .catch(error => {
          console.log(error);
        });
    },
    reroute(pos) {
      if (pos == "owner") {
        this.$router.push({ path: "/bizhome" });
      } else {
        this.$router.push({ path: "/" });
      }
    }

BizHome.vue

Это страница, на которую при успешном входе происходит перенаправление

created: function() {
    this.getLocations();
  },
  methods: {
    getLocations() {
      API.get("business/")
        .then(response => {
          this.biz = response.data;
        })
        .catch(error => {
          console.log(error);
        });

      API.get("locations/")
        .then(response => {
          this.bizLocations = response.data;
        })
        .catch(error => {
          console.log(error);
        });
    },
  }

решение

Используя некоторые советы, которые я получил от YuuwakU ниже, я добавил заголовки непосредственно к вызовам get в методе getLocations, чтобы перезаписать заголовки экземпляров axios.Оказалось, что новая страница загружена до обновления токена в экземпляре.Однако одним из недостатков этого решения является то, что мне теперь нужно напрямую добавлять заголовки ко всем звонкам, которые я делаю.Заголовки в экземпляре никогда не обновляются.Я добавил API.defaults.headers.common['Authorization'] = 'JWT ' + result.data.token; в метод подтверждения успешного извлечения токена, который должен был обновить токен для экземпляра.Это не сработало для меня, если у кого-то есть идеи, мне было бы интересно услышать их

edit 2

Я выяснил, почему экземпляр axios не обновил его, потому что я пыталсяполучить токен из локального строба в api.js, и он переопределил его.Теперь это работает, но токен не является постоянным, так что это тоже не идеально.Я буду обновлять, если я найду лучшее решение.

Окончательное обновление

Я наконец-то нашел хорошее решение.Я удалил заголовок авторизации из экземпляра axios в api.js, затем удалил все заголовки из всех вызовов axios.В методе подтверждения при успешном входе в систему я добавил эту строку, упомянутую ранее API.defaults.headers.common['Authorization'] = 'JWT ' + result.data.token;, а также добавил токен в локальное хранилище.У меня есть метод проверки токена, который запускается до загрузки страниц.В этом методе перед отправкой запроса на подтверждение токена я добавил API.defaults.headers.common['Authorization'] = 'JWT ' + localstorage.getItem('token');.Это позволяет пользователю перемещаться по сайту и возвращаться, а также использовать токен, если он действителен, и не требует установки заголовков при каждом вызове.

1 Ответ

0 голосов
/ 02 февраля 2019

Причина, по которой это происходит, заключается в том, что экземпляр axios уже создан с токеном с истекшим сроком действия, который существует в localStorage.Таким образом, вы должны убедиться, что экземпляр axios обновлен с новым токеном после входа в систему, в противном случае вы будете использовать старый токен до перезагрузки новой страницы.Попробуйте следующее:

import axios from 'axios'

export default axios.create({
  baseURL: `http://127.0.0.1:8000/`,
  headers: {
    'Content-Type': 'application/json',
    Authorization() { // Converted to a method, similar concept to a vue data property
      return `JWT  ${localStorage.getItem('token')}`,
    }
  },
  xsrfCookieName: 'csrftoken',
  xsrfHeaderName: 'X-CSRFToken',
  withCredentials: true
})

ИЛИ, вы даже можете использовать аксиальные перехватчики для выборки из localStorage с каждым запросом:

// Add a request interceptor
axios.interceptors.request.use(config => {
    // Do something before request is sent
    config.headers = {
      'Content-Type': 'application/json',
      Authorization: 'JWT ' + localStorage.getItem('token')
    }
    return config
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...