vue axios tokenリフレッシュ--vueバックグラウンド管理
需要
最近、プロジェクトを書き、バックエンドとtokenリフレッシュスキームについて議論しています.フロントエンドがログインした後、バックエンドはtokenと
ぶんせき
フロントエンドログイン後は
方法1:要求を開始した後、tokenが期限切れになった後にrefreshTokenインタフェースを呼び出して新しいtokenを取得し、バーの前の要求を実行します.
方法2:バックエンドにtokenの期限切れのフィールドが提供され、要求が開始される前に各要求をブロックし、tokenの有効時間が期限切れであるかどうかを判断し、期限切れであれば要求を保留し、tokenをリフレッシュしてから要求を継続する.
インプリメンテーション
ここでは、バックエンドにデータを返すことを約束する方法を実装します.例えば、次のようにします.
最適化
質問:
tokenが期限切れになった場合、refreshTokenメソッドを呼び出した後、新しいtokenを取得して送信する前のリクエストを送信します.このとき、バックエンドが処理されていなければ400ステータスコードに戻ってcatchに入り、再ログインの操作を実行する必要があります.
解決方法:catchでtokenの削除とログインページへのジャンプ操作を行う必要はありません.
完全なコード
みんなに役に立つことを望みます!!
最近、プロジェクトを書き、バックエンドとtokenリフレッシュスキームについて議論しています.フロントエンドがログインした後、バックエンドはtokenと
refreshToken
の有効時間に戻り、tokenが期限切れになったときにrefreshToken
で新しいtokenを取得する必要があります.フロントエンドはtokenを無痛にリフレッシュする必要があります.つまり、tokenのリフレッシュを要求するときは、ユーザーが感知しないようにします.ぶんせき
フロントエンドログイン後は
token
とrefreshToken
に戻ります.token
30分失効refreshToken
1日失効、この時間差で無痛リフレッシュtoken方法1:要求を開始した後、tokenが期限切れになった後にrefreshTokenインタフェースを呼び出して新しいtokenを取得し、バーの前の要求を実行します.
refreshToken
が期限切れになったら、直接ログインページに戻ります.方法2:バックエンドにtokenの期限切れのフィールドが提供され、要求が開始される前に各要求をブロックし、tokenの有効時間が期限切れであるかどうかを判断し、期限切れであれば要求を保留し、tokenをリフレッシュしてから要求を継続する.
インプリメンテーション
ここでは、バックエンドにデータを返すことを約束する方法を実装します.例えば、次のようにします.
{code: 418, message: 'token ', data: {}}
import axios from "axios";
const instance = axios.create({
baseURL: process.env.BASE_API, // url = base url + request url
// timeout: 5000 // request timeout
withCredentials: true,
});
// setToken , token header, token localStorage
instance.setToken = (token,refreshToken) => {
instance.defaults.headers['Authorization'] = `Auth ${token}`
// localStorage
window.localStorage.setItem('token', token)
window.localStorage.setItem('refreshToken', refreshToken)
}
function refreshToken () {
// token token refreshToken
window.localStorage.setItem('token', window.localStorage.refreshToken)
return instance({method:'post',url: '/api-token-refresh'})
}
// token
function removeToken () {
window.localStorage.removeItem('token')
window.localStorage.removeItem('refreshToken')
}
//
instance.interceptors.request.use(
config => {
// vuex token
// , http header token, token
// token, token ,
const token = window.localStorage.token;
token && (config.headers.Authorization = `Auth ${token}`);
return config;
},
error => {
return Promise.error(error);
}
);
//
let isRefreshing = false
// ,
let requests = []
//
instance.interceptors.response.use(
response => {
const res = response.data
if(res.code === 418){
const config = response.config
if (!isRefreshing) {
isRefreshing = true
return refreshToken().then(res => {
const { token ,refreshToken} = res.data
instance.setToken(token,refreshToken)
config.headers['Authorization'] = `Auth ${token}`
config.baseURL = ''
console.log('token ');
//
// token,
requests.forEach(cb => cb(token))
requests = []
return instance(config)
},err=>{
console.log(err)
}).catch(res => {
removeToken()
router.push('/login')
console.error('refreshtoken error =>', res)
}).finally(() => {
console.log(' ');
isRefreshing = false
})
}else {
// token, resolve promise
//
//
return new Promise((resolve) => {
// resolve , , token
requests.push((token) => {
config.baseURL = ''
config.headers['Authorization'] = `Auth ${token}`
resolve(instance(config))
})
})
}
}
if (res.code === 0) {
//
return Promise.reject(res);
// return res
}
return res
},
error => {
console.log(error);
return Promise.reject();
}
);
export { instance };
最適化
質問:
tokenが期限切れになった場合、refreshTokenメソッドを呼び出した後、新しいtokenを取得して送信する前のリクエストを送信します.このとき、バックエンドが処理されていなければ400ステータスコードに戻ってcatchに入り、再ログインの操作を実行する必要があります.
解決方法:catchでtokenの削除とログインページへのジャンプ操作を行う必要はありません.
refreshToken
が期限切れになると、バックエンドは{code: 419, message: 'refreshToken , ', data: {}}
に戻ります.もちろん、tokenが合法ではないtokenが認証されていない場合もあります.完全なコード
import axios from "axios";
const instance = axios.create({
baseURL: process.env.BASE_API, // url = base url + request url
// timeout: 5000 // request timeout
withCredentials: true,
});
// setToken , token header, token localStorage
instance.setToken = (token,refreshToken) => {
instance.defaults.headers['Authorization'] = `Auth ${token}`
// localStorage
window.localStorage.setItem('token', token)
window.localStorage.setItem('refreshToken', refreshToken)
}
function refreshToken () {
// token token refreshToken
window.localStorage.setItem('token', window.localStorage.refreshToken)
return instance({method:'post',url: '/api-token-refresh'})
}
// token
function removeToken () {
window.localStorage.removeItem('token')
window.localStorage.removeItem('refreshToken')
}
//
instance.interceptors.request.use(
config => {
// vuex token
// , http header token, token
// token, token ,
const token = window.localStorage.token;
token && (config.headers.Authorization = `Auth ${token}`);
return config;
},
error => {
return Promise.error(error);
}
);
//
let isRefreshing = false
// ,
let requests = []
//
instance.interceptors.response.use(
response => {
const res = response.data
// refreshToken token token
if(res.code === 419||420||421){
removeToken()
router.push('/login')
return Promise.reject(res);
}
if(res.code === 418){
const config = response.config
if (!isRefreshing) {
isRefreshing = true
return refreshToken().then(res => {
const { token ,refreshToken} = res.data
instance.setToken(token,refreshToken)
config.headers['Authorization'] = `Auth ${token}`
config.baseURL = ''
console.log('token ');
//
// token,
requests.forEach(cb => cb(token))
requests = []
return instance(config)
},err=>{
console.log(err)
}).catch(res => {
console.error('refreshtoken error =>', res)
}).finally(() => {
console.log(' ');
isRefreshing = false
})
}else {
// token, resolve promise
//
//
return new Promise((resolve) => {
// resolve , , token
requests.push((token) => {
config.baseURL = ''
config.headers['Authorization'] = `Auth ${token}`
resolve(instance(config))
})
})
}
}
if (res.code === 0) {
//
return Promise.reject(res);
// return res
}
return res
},
error => {
console.log(error);
return Promise.reject();
}
);
export { instance };
みんなに役に立つことを望みます!!