如何在React中使用刷新令牌

4
我有一个像这样的获取刷新令牌的URL:client.com/api//auth/refresh-token,但我很难使用它。我认为登录后应该在本地存储中保存刷新令牌,但我该如何使用它呢? login.tsx
export const useLogin = () => {

    const LoginAuth = async (data: AuthenticationProps) => {
        await axios.post(baseURL + `client/auth/login`,
        {
            email: data.email,
            password: data.password,
        },
        {
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json",
            }
        }
        )
        .then((res) => {
            if(res.status === 200) {
                console.log("success")
            }
        }, (err) => {
            console.log(err);
        })
        
    }
    return {
        LoginAuth,
    }
}

一个安全建议:将您的refreshToken保存在http-only保护cookie中,将您的accessToken保存在内存中(在状态中)。 - Amin
看到有5个正确答案,但没有标记为已接受的答案,我需要澄清您的疑问:您想知道如何保存刷新令牌吗?还是您想知道如何获取先前保存的刷新令牌?或者您想知道如何使用刷新令牌在后面访问令牌失效时更新访问令牌?还是所有这些都想知道? - Osmanys Fuentes-Lombá
6个回答

7

不应将刷新令牌存储在本地存储中,这会导致安全漏洞,因为本地存储可被JavaScript访问,而且刷新令牌是长期令牌(存活时间比访问令牌长),你应该将访问令牌存储在本地存储中,因为访问令牌是短期令牌,将其存储在本地存储或cookie中完全没有问题,然后你应该在React中调用useEffect(),检查令牌何时过期,然后进行调用。以下是一个小例子:

import Cookies from 'js-cookie';
axios.get("ur_url_here/",data,{withCredentials:true}).then((res)=>{
                Cookies.set(res.data.access) // assuming the response has the access token
        
}))

// now we check the expiration of access token

useEffect(()=>{
   if(!(Cookies.get("access"))){
      axios.get("refresh_url_here/",{withCredentials:true}).then((res)=>{
        Cookies.set(res.data.access)
})
/*what you do here, is try to have a 
resource/view in your backend that has 
the refresh token and make request to it 
so that it gives you a new access token, 
because refresh token should be in cookies tagged with `httponly', 
then you can send the access token to client side 
as a response and set it somewhere.
*/
}
   else{
      //do something else
}
},[])

这是一段简化的代码,但足以清楚地解释刷新令牌的安全方式。

另外需要注意的是,我将访问令牌存储在cookies中,但你也可以使用同样的方法将其存储在本地存储中。


你没有说要把刷新令牌存储在哪里? - Amin
1
@Amin 晚回答了,看一下 useEffect() 后面的代码注释。 - Ghazi
1
这意味着您正在构建一个可以设置HttpOnly cookie的有状态API。所提供的解决方案不适用于客户端和后端位于不同顶级域的无状态API。 - kidA
@kidA 我认为作者的意思是,刷新令牌应该从客户端的 cookies 中提取,并在请求体内发送到服务器中。 - William Le

2

将其保存在本地存储中

export const storeToken = async (token: string) => {
  await AsyncStorage.setItem('@token', token);
};

需要时从存储中获取

export const getToken = async () => {
  return await AsyncStorage.getItem('@token');
};

当应用程序启动或从API获取令牌时,您应该从存储中提取令牌并在使用应用程序时将其存储在状态或类似位置。


1

将刷新令牌存储在本地存储中是最好的方式。

将令牌设置在本地存储中,

localStorage.setItem("token", token); 

从本地存储获取令牌

let token = localStorage.getItem("token");

您也可以像下面这样在浏览器中查看存储的令牌:

enter image description here


1

保存在 Web 存储

只能在 Web 存储中存储字符串

本地存储(LocalStorage)

即使关闭并重新打开浏览器,数据仍将保留。

获取(Get)

const token = localStorage.getItem('token');

集合

localStorage.setItem('token', 'value')

SessionStorage

在浏览器关闭时会被删除的数据。

获取

sessionStorage.getItem('token', 'value')

设置

sessionStorage.setItem('token', 'value')

1
您可以使用本地存储(LocalStorage)或会话存储(SessionStorage)来实现此功能。
export const useLogin = () => {

    const LoginAuth = async (data: AuthenticationProps) => {
        await axios.post(baseURL + `client/auth/login`,
        {
            email: data.email,
            password: data.password,
        },
        {
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json",
            }
        }
        )
        .then((res) => {
            if(res.status === 200) {
                console.log("success")
                window.localstorage.setItem('authToken', res.data.token);
                // Same as session storage
                // window.localstorage.setItem('authToken', res.data.token);
            }
        }, (err) => {
            console.log(err);
        })
        
    }
    
    return {
        LoginAuth,
    }
}

您可以在这里查看它们之间的区别。


0

所有与Web应用程序逻辑过程相关的安全措施都以提供访问令牌和刷新令牌的方式结束,然后由您负责保护它们的安全。只要这些令牌有效,它们就是使访问成为可能的必需品。实际上,如果您查看OIDC流程,大多数情况下访问令牌甚至不会被传递给浏览器,因为浏览器在安全方面存在许多已知的弱点。

保持或存储这些令牌的最佳方法是通过后台渠道处理它们,如果不是,则使用自定义逻辑在浏览器中加密并存储在本地存储中,以便只有您的应用程序知道如何使用这些令牌。

更好的方法是让后端代码为您完成此部分,因为您知道JavaScript始终是公开且可检索的。

希望这可以帮助到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接