在现代 web 应用程序中,JWT(JSON Web Token)是一种非常流行的用户身份验证机制。由于其无状态和自包含的特性,JWT 在实现分布式系统时显得尤为重要。然而,JWT 的有效期限制也给开发者带来了挑战。为了解决这一问题,我们可以采用 JWT 自动续期的策略来提升用户体验。

什么是 JWT?

JWT 是一种开放标准,用于在各方之间安全地传递信息。JWT 由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。这三部分使用点(.)连接成一个字符串。

头部示例

{
  "alg": "HS256",
  "typ": "JWT"
}

载荷示例

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516243022
}

签名生成

签名是利用头部和载荷通过指定算法加密生成的。在实际开发中,JWT 会指定一个过期时间(exp),超出该时间后,用户需要重新登录才能获取新的 JWT。

JWT 自动续期的实现

为了避免用户频繁登录,我们可以在 JWT 的有效期快到时自动续期。这里我们将通过前端和后端的协作来实现自动续期。

前端实现

前端使用 JavaScript 进行 JWT 自动续期的重要步骤包括:

  1. 监听用户操作以检测 JWT 的过期时间。
  2. 当检测到 JWT 快要过期(比如小于 5 分钟)时,发起请求获取新的 JWT。
function getJwt() {
    return localStorage.getItem('jwt'); // 从 localStorage 获取 JWT
}

function checkJwtExpiration() {
    const jwt = getJwt();
    if (!jwt) return;

    const payload = JSON.parse(atob(jwt.split('.')[1]));
    const exp = payload.exp * 1000; // 转换为毫秒
    const currentTime = Date.now();

    // 如果 JWT 过期时间小于当前时间加上 5 分钟,则自动续期
    if (exp < currentTime + 5 * 60 * 1000) {
        renewJwt(jwt);
    }
}

function renewJwt(oldJwt) {
    fetch('/api/renew', {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${oldJwt}`,
            'Content-Type': 'application/json'
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.newJwt) {
            localStorage.setItem('jwt', data.newJwt); // 更新 JWT
        }
    })
    .catch(error => {
        console.error('Renew JWT Failed:', error);
    });
}

// 监听用户的活动
setInterval(checkJwtExpiration, 30000); // 每 30 秒检查一次

后端实现

后端需要提供一个新的 API 接口来处理 JWT 的续期请求。下面是一个基于 Node.js 的示例:

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

app.use(express.json());

const SECRET_KEY = 'your_secret_key'; // 密钥
const TOKEN_EXPIRY = '1h'; // 原 token 有效时间

app.post('/api/renew', (req, res) => {
    const token = req.headers['authorization'].split(' ')[1];

    jwt.verify(token, SECRET_KEY, (err, decoded) => {
        if (err) {
            return res.status(401).json({ message: 'Token is invalid' });
        }

        // 生成新的 token
        const newToken = jwt.sign({ sub: decoded.sub }, SECRET_KEY, { expiresIn: TOKEN_EXPIRY });
        res.json({ newJwt: newToken });
    });
});

// 启动服务
app.listen(3000, () => {
    console.log('Server started on http://localhost:3000');
});

总结

通过上述方法,我们实现了 JWT 的自动续期机制,提升了用户体验。前端通过监听 JWT 的过期时间,适时请求续期;后端提供了新的联机 API 来签发新的 JWT。这种方法有效地减少了用户频繁登录的麻烦,使应用程序更加友好。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部