Я строю API, используя колбу-restful с токенами jwt для авторизации с помощью vue-интерфейса, используя axios для запросов. Запросы работают правильно, а теги jwt_required и jwt_refresh_token работают должным образом. Я могу войти, я могу получить данные и т.д. без проблем. Проблема, с которой я столкнулся, заключается в том, что я хочу, чтобы пользователь обновил свой токен, если попытался сделать запрос, и произошла неавторизованная ошибка состояния 401, поскольку срок действия маркера истек. Ошибка возвращается как строка, а не как фактическая ошибка, поэтому я не могу проверить «error.status» или получить «error.config», чтобы повторно отправить неудавшийся запрос после обновления токена и обновления заголовков. Я не думаю, что это проблема аксиоса, я думаю, что это проблема cors. Я абсолютно не знаю, что для этого сделать, и я ударил стену после нескольких часов поиска ответов. Я пытался реализовать некоторые решения для подобных проблем, но они не помогли, поэтому я подумал, что должен спросить, как конкретно решить мою проблему, и, надеюсь, ответы могут помочь кому-то еще в будущем.
Я планировал использовать перехватчики axios. Установите токен в перехватчике запроса и используйте перехватчик ответа, чтобы обновить токен в ответе статуса 401 и повторно отправить ранее неудавшийся запрос.
Это моя настройка CORS в колбе
cors = CORS(app, resources={r"/*": {"origins": "*"}}, support_credentials=True, headers=['Content-Type', 'Authorization', 'Access-Control-Allow-Credentials', 'Access-Control-Allow-Origin'],
expose_headers='Authorization')
Это мой путь обновления токена
class TokenRefresh(Resource):
@jwt_refresh_token_required
def post(self):
username = get_jwt_identity()
current_user = User.find_by_username(username)
if current_user:
access_token = create_access_token(identity=username)
refresh_token = create_refresh_token(identity=username)
return {
'access_token': access_token,
'refresh_token': refresh_token
}
else:
return 'Not a User'
Это моя установка Axios
const API_URL = process.env.VUE_APP_BASE_URL
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers.post['Access-Control-Allow-Origin'] = '*';
axios.defaults.baseURL = API_URL
axios.interceptors.request.use(config => {
let token = localStorage.getItem('access_token')
if (config.url.includes('token/refresh')){
token = localStorage.getItem('refresh_token')
}
config.headers.Authorization = `Bearer ${token}`
return config;
},
error => {
return Promise.reject(error)
})
axios.interceptors.response.use(response => response, error => {
console.log(error)
console.log(error.status)
})
В ответе я хочу обновить токен и повторно отправить старый запрос, но ошибка возвращается в виде строки, а error.status возвращается как неопределенный. Я хотел бы, если возможно, обновить токен с помощью действия vuex, чтобы мои токены могли одновременно храниться в состоянии. Модель того, что я имел в виду, но не работает, выглядит примерно так
axios.interceptors.response.use(response => response, error => {
if (error.status === 401){
this.dispatch('refreshUser')
let newtoken = localStorage.getItem('access_token')
error.headers.Authorization = `Bearer ${newtoken}`
return axios.request(error.config)
}
})
// from vuex store
const actions = {
async userRefresh({ commit }) {
const response = await axios.post(`/token/refresh`,'test')
commit('REFRESH_USER', response.data)
},
const mutations = {
REFRESH_USER: (state, resp) =>{
state.jwt.access_token = resp.access_token
localStorage.setItem('access_token',resp.access_token)
state.jwt.refresh_token = resp.refresh_token
localStorage.setItem('refresh_token',resp.refresh_token)
},
Следующий вопрос: можно ли отправить действие vuex из того места, где я хотел бы его отправить?
Это мой первый проект такого рода, но я прошу прощения за свое невежество.
Спасибо!