Gre*_*han 14 javascript jwt reactjs bearer-token react-native
我使用以下中间件在到期时刷新我的令牌:
import {AsyncStorage} from 'react-native';
import moment from 'moment';
import fetch from "../components/Fetch";
import jwt_decode from 'jwt-decode';
/**
* This middleware is meant to be the refresher of the authentication token, on each request to the API,
* it will first call refresh token endpoint
* @returns {function(*=): Function}
* @param store
*/
const tokenMiddleware = store => next => async action => {
if (typeof action === 'object' && action.type !== "FETCHING_TEMPLATES_FAILED") {
let eToken = await AsyncStorage.getItem('eToken');
if (isExpired(eToken)) {
let rToken = await AsyncStorage.getItem('rToken');
let formData = new FormData();
formData.append("refresh_token", rToken);
await fetch('/token/refresh',
{
method: 'POST',
body: formData
})
.then(response => response.json())
.then(async (data) => {
let decoded = jwt_decode(data.token);
console.log({"refreshed": data.token});
return await Promise.all([
await AsyncStorage.setItem('token', data.token).then(() => {return AsyncStorage.getItem('token')}),
await AsyncStorage.setItem('rToken', data.refresh_token).then(() => {return AsyncStorage.getItem('rToken')}),
await AsyncStorage.setItem('eToken', decoded.exp.toString()).then(() => {return AsyncStorage.getItem('eToken')}),
]).then((values) => {
return next(action);
});
}).catch((err) => {
console.log(err);
});
return next(action);
} else {
return next(action);
}
}
function isExpired(expiresIn) {
// We refresh the token 3.5 hours before it expires(12600 seconds) (lifetime on server 25200seconds)
return moment.unix(expiresIn).diff(moment(), 'seconds') < 10;
}
};
export default tokenMiddleware;
Run Code Online (Sandbox Code Playgroud)
和获取助手:
import { AsyncStorage } from 'react-native';
import GLOBALS from '../constants/Globals';
import {toast} from "./Toast";
import I18n from "../i18n/i18n";
const jsonLdMimeType = 'application/ld+json';
export default async function (url, options = {}, noApi = false) {
if ('undefined' === typeof options.headers) options.headers = new Headers();
if (null === options.headers.get('Accept')) options.headers.set('Accept', jsonLdMimeType);
if ('undefined' !== options.body && !(options.body instanceof FormData) && null === options.headers.get('Content-Type')) {
options.headers.set('Content-Type', jsonLdMimeType);
}
let token = await AsyncStorage.getItem('token');
console.log({"url": url,"new fetch": token});
if (token) {
options.headers.set('Authorization', 'Bearer ' + token);
}
let api = '/api';
if (noApi) {
api = "";
}
const link = GLOBALS.BASE_URL + api + url;
return fetch(link, options).then(response => {
if (response.ok) return response;
return response
.json()
.then(json => {
if (json.code === 401) {
toast(I18n.t(json.message), "danger", 3000);
AsyncStorage.setItem('token', '');
}
const error = json['message'] ? json['message'] : response.statusText;
throw Error(I18n.t(error));
})
.catch(err => {
throw err;
});
})
.catch(err => {
throw err;
});
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
next(action)
应该调用该方法./templates
端点在/token/refresh
使用旧的过期令牌之前(而不是之后)被调用...编辑:为了这个问题,我修改了我的代码,把它放到一个文件中.我还放了一些console.log来显示这段代码的执行方式
我们从图像中可以看出:
对此有何帮助?
编辑直到赏金结束:
从这个问题我试着理解为什么我的方法对中间件是错误的,因为我在互联网上发现的许多资源都将中间件作为实现刷新令牌操作的最佳解决方案.
我的处理设置略有不同。我没有在中间件中处理刷新令牌逻辑,而是将其定义为辅助函数。这样我就可以在我认为合适的任何网络请求之前执行所有令牌验证,并且任何不涉及网络请求的 redux 操作都不需要此函数
export const refreshToken = async () => {
let valid = true;
if (!validateAccessToken()) {
try {
//logic to refresh token
valid = true;
} catch (err) {
valid = false;
}
return valid;
}
return valid;
};
const validateAccessToken = () => {
const currentTime = new Date();
if (
moment(currentTime).add(10, 'm') <
moment(jwtDecode(token).exp * 1000)
) {
return true;
}
return false;
};
Run Code Online (Sandbox Code Playgroud)
现在我们有了这个辅助函数,我为所有需要的 redux 操作调用它
const shouldRefreshToken = await refreshToken();
if (!shouldRefreshToken) {
dispatch({
type: OPERATION_FAILED,
payload: apiErrorGenerator({ err: { response: { status: 401 } } })
});
} else {
//...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
469 次 |
最近记录: |