【图文并茂】ant design pro 如何使用 refresh token 可续期 token 来提高用户体验

在这里插入图片描述
上一节 * 【图文并茂】ant design pro 如何对接后端个人信息接口

json web token

在这里插入图片描述
我们知道 token 就像身份证一样,但是它是有个过期时间的

比如说设为一个小时,

就像我们去访问微信支付那样,它们的 token 就是一个小时。

那我们的系统,你现在登录之后,你设了一个小时,过期时间,那它就在你登录之后的一个小时内一定会过期

无论你在中间有没有做访问

refresh token

问题出在这里,你中间一小时内,一直在操作,该过期还得过期,过期了,就要重新登录,未免体验太差了

我要的是,比如在一个如果中间有操作,你就帮我续下期。

比如说的这个中间,是七天内,只要七天内,当然你自己定,一天内也行,一天内只要有操作,你就一直帮我续一个小时。

这个时间是自己定的。

这里就涉及到两个时间。

JWT_EXPIRE=1d
REFRESH_JWT_EXPIRE=7d

比如这里有两个过期时间。

先看最后一个。

比如我现在登录了,那七天后会过期,我明天还有在操作,那就是七天后之后的过一天会过期

意思是,你只要在 REFRESH_JWT_EXPIRE 有效期内,有操作,那就一直延后七天,一直续。

也就是说这个时候会生成新的

REFRESH_JWT_SECRET

两个时间对应两个 token 的

JWT_SECRET


REFRESH_JWT_SECRET 这个是来续期用的

JWT_SECRET 这个应该叫 access_token ,来访问 api 用的,来验证的

所以 JWT_SECRET 这个可以设短一些,比如 一个小时。

一个小时后就过期了,别人拿到旧的也没用。

后端实现

先要实现 refresh Token 的 api

const refreshToken = handleAsync(async (req: Request, res: Response) => {
  try {
    const { refreshToken } = req.body;

    if (!refreshToken) {
      res.status(401);
      throw new Error('You are not authenticated!');
    }

    const decoded = jwt.verify(refreshToken, process.env.REFRESH_JWT_SECRET as string) as DecodedToken;
    const newRefreshToken = generateRefreshToken(decoded.id);

    res.json({
      success: true,
      token: generateToken(decoded.id),
      refreshToken: newRefreshToken,
    });
  } catch (err) {
    console.error(err);
    res.status(401);
    throw new Error(err.message || 'Not authorized, token failed');
  }
});

这里很简单,用旧的 refresh token 换新的,时间重新计算,继续延后七天,生成新的 access token 和 refresh token

新的 access token 可以让应用继续访问,

新的 refresh token 可以让租期延后。

所以 refresh token 从来不是解决安全问题的,只是解决体验问题。

const decoded = jwt.verify(refreshToken, process.env.REFRESH_JWT_SECRET as string) as DecodedToken;

这里总会验证老的 refresh. token 是否有效的。

如果无效,也就没后面啥事了。

前端实现

之前这里 【图文并茂】ant design pro 如何给后端发送 json web token - 请求拦截器的使用

要继续改一下。

  requestInterceptors: [
    async (config: RequestOptions) => {
      // 拦截请求配置,进行个性化处理。
      const url = config?.url;
      const accessToken = localStorage.getItem('token');

      if (url?.includes('/auth/refresh') || url?.includes('/auth/login')) {
        return {
          ...config,
          headers: { Authorization: `Bearer ${accessToken}` },
          url,
        };
      }

      let newToken;

      // refresh token
      if (accessToken) {
        const currentDate = new Date();
        const decodedToken: DecodedToken = jwtDecode<DecodedToken>(accessToken);

        // expired
        if (decodedToken.exp * 1000 < currentDate.getTime()) {
          // send refresh token
          const response = await refreshToken({
            refreshToken: localStorage.getItem('refreshToken')!,
          });
          if (response.success) {
            localStorage.setItem('token', response.token);
            localStorage.setItem('refreshToken', response.refreshToken);

            newToken = response.token;
          }
        }
      }

      return {
        ...config,
        headers: { Authorization: `Bearer ${newToken ?? accessToken}` },
        url,
      };
    },
  ],

那个请求请求拦截器部分要这样做

  if (url?.includes('/auth/refresh') || url?.includes('/auth/login')) {
    return {
      ...config,
      headers: { Authorization: `Bearer ${accessToken}` },
      url,
    };
  }

这里只是过滤掉不必要的 api

接下来

if (decodedToken.exp * 1000 < currentDate.getTime()) {

就去判断 access token 是否过期,过期才要续

只要 refresh token 不过期,总能续上新的

headers: { Authorization: Bearer ${newToken ?? accessToken} },

后面这里只是用续上的来代替旧的。

到此完成。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用 `rest_framework_jwt` 进行 token 续期需要执行以下步骤: 1. 在 `settings.py` 中添加 `JWT_ALLOW_REFRESH` 配置项: ```python JWT_AUTH = { # ... 其他配置项 ... 'JWT_ALLOW_REFRESH': True, 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7), } ``` 其中,`JWT_ALLOW_REFRESH` 配置项表示是否允许使用 refresh token 进行 token 续期,`JWT_REFRESH_EXPIRATION_DELTA` 配置项表示 refresh token 的有效期,这里设置为 7 天。 2. 在 `urls.py` 中添加 `refresh_jwt_token` 视图的路由: ```python from rest_framework_jwt.views import refresh_jwt_token urlpatterns = [ # ... 其他路由 ... path('api/token/refresh/', refresh_jwt_token), ] ``` 3. 在前端代码中,当 token 过期后,使用 refresh token 进行 token 续期。示例代码如下: ```javascript const refreshToken = localStorage.getItem('refreshToken'); if (refreshToken) { fetch('/api/token/refresh/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ refresh: refreshToken }), }) .then((response) => response.json()) .then((data) => { localStorage.setItem('accessToken', data.access); localStorage.setItem('refreshToken', data.refresh); }) .catch((error) => { console.error('Failed to refresh token', error); }); } else { console.error('No refresh token found'); } ``` 在上面的代码中,我们首先从本地存储中获取 refresh token,然后使用 `fetch` 发送 POST 请求到 `/api/token/refresh/` 视图,将 refresh token 作为请求体的 `refresh` 参数。在成功获取到新的 access tokenrefresh token 后,我们将它们保存到本地存储中。 希望这可以帮助你理解如何使用 `rest_framework_jwt` 进行 token 续期
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值