在哪里检查令牌到期并发送刷新请求

时间:2020-04-14 03:26:22

标签: react-admin

我已经设置了react-admin并将其与HydraAdmin组件一起使用。
我的登录请求返回一个JWT和一个刷新令牌。我将它们存储在localStorage中,并希望在发送请求之前检查JWT是否已过期。

问题是,我该在哪里做?
我尝试了我的身份验证提供程序的checkAuth函数,但是在每次提取之前(例如POST)都不会调用它。

我希望能够可靠地刷新令牌,然后再发送请求。
还是这不是解决这个问题的正确方法?

1 个答案:

答案 0 :(得分:0)

我通过将我的refreshToken函数调用添加到每个数据提供程序函数中来解决了该问题。 不知道这是否是正确的方法,但是确实有效。

我的刷新令牌的功能:

function setAuth(auth) {
    localStorage.setItem('token', auth.token);
    localStorage.setItem('refreshToken', auth.refreshToken);
    authHeaders.set("Authorization", `Bearer ${auth.token}`);
}

function getRefreshToken() {
    return localStorage.getItem('refreshToken');
}

function getToken() {
    return localStorage.getItem('token');
}

function isLoggedIn() {
    return getToken() && getRefreshToken();
}

function isTokenExpired() {
    const decoded = jwt_decode(getToken());
    return decoded.exp < Date.now() / 1000 + 60 * 5;
}

function postRequest(route, body) {
    return fetch(new Request(url(config.server, route), {
        method: 'POST',
        body: JSON.stringify(body),
        headers: new Headers({ 'Content-Type': 'application/json' }),
    }));
}    

export async function refreshToken() {
    if (!isLoggedIn()) {
        return;
    }

    if (isTokenExpired()) {
        const response = await postRequest(config.auth.refresh_route, {refreshToken: getRefreshToken()});
        if (response.ok) {
            setAuth(await response.json());
        }
    }
}

我的数据提供者:

export const authHeaders = new Headers();
const fetch = (url, options = {}) => fetchHydra(url, {...options, headers: authHeaders });
const provider = hydraDataProvider(config.api, fetch);

class DataProvider {

    async introspect() {
        await refreshToken();
        return provider.introspect();
    }

    async getList (resource, params) {
        await refreshToken();
        return provider.getList(resource, params);
    }

    async getOne (resource, params) {
        await refreshToken();
        return provider.getOne(resource, params);
    }

    async getMany (resource, params) {
        await refreshToken();
        return provider.getMany(resource, params);
    }

    async getManyReference (resource, params) {
        await refreshToken();
        return provider.getManyReference(resource, params);
    }

    async create (resource, params) {
        await refreshToken();
        return provider.create(resource, params);
    }

    async update (resource, params) {
        await refreshToken();
        return provider.update(resource, params);
    }

    async updateMany (resource, params) {
        await refreshToken();
        return provider.updateMany(resource, params);
    }

    async delete (resource, params) {
        await refreshToken();
        return provider.delete(resource, params);
    }

    async deleteMany (resource, params) {
        await refreshToken();
        return provider.deleteMany(resource, params);
    }
}

export const dataProvider = new DataProvider();