令牌jwt未过期

问题描述 投票:0回答:1

令牌(用于测试)我只让它持续 60 秒,但它似乎永远不会过期。通过 Postman 上的承载,getInfo 路由不断给我一个响应,就好像令牌在 60 秒后仍然有效一样。我可能做错了什么?

我有这个文件夹树:

├── app.js
├── node_modules
├── package-lock.json
├── package.json
├── private
│   ├── private.key
│   └── public.key
├── public
│   ├── html
│   │   └── cover.html
│   └── images
│       ├── logo-w.png
│       └── logo.png
├── request.http
├── src
│   ├── auth
│   │   ├── authService.js
│   │   └── tokenManager.js
│   ├── middleware
│   │   └── authMiddleware.js
│   └── routes
│       ├── auth.js
│       └── info.js

我有不同的文件,但主文件是app.js

const express = require("express");
const path = require("path");
const port = process.env.PORT || 3000;
const app = express();
const fs = require('fs');
const jwt = require('jsonwebtoken');

require('dotenv').config();

app.use(express.static("public"));

app.use(express.json());

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "public/html", "cover.html"));
});

const infoRoute = require("./src/routes/info");
const authRoute = require("./src/routes/auth");

app.use("/info", infoRoute);
app.use("/auth", authRoute);

app.listen(port, () => {
  console.log("Server Is Running On Port", port);
});

在我的 authService.js 中,我模拟了一个简单的登录来进行测试:

const { issueJWT, issueRefreshToken } = require('./tokenManager');
const users = [{ id: 1, username: 'test', password: 'password' }];

const login = (username, password) => {
  const user = users.find(u => u.username === username && u.password === password);
  if (!user) throw new Error('Credentials not valid');

  const tokenObject = issueJWT(user);
  const refreshToken = issueRefreshToken(user);
  return {
    ...tokenObject,
    refreshToken: refreshToken
  };
};

module.exports = { login };

在我的 tokenManager.js 中

const jwt = require('jsonwebtoken');
const fs = require('fs');
const path = require('path');

const PRIV_KEY = fs.readFileSync(path.join(__dirname, '../../private/private.key'), 'utf8');

const issueJWT = (user) => {
  const expiresIn = 60;
  const payload = {
    sub: user.id,
    iat: Date.now(),
  };
  const signedToken = jwt.sign(payload, PRIV_KEY, { expiresIn: expiresIn, algorithm: 'RS256' });
  return {
    token: "Bearer " + signedToken,
    expires: expiresIn
  };
};

const issueRefreshToken = (user) => {
  const expiresIn = '7d';
  const payload = {
    sub: user.id,
    iat: Date.now(),
  };
  const refreshToken = jwt.sign(payload, PRIV_KEY, { expiresIn: expiresIn, algorithm: 'RS256' });
  return refreshToken;
};

module.exports = { issueJWT, issueRefreshToken };

在我的 authMiddleware.js 中


const jwt = require('jsonwebtoken');
const fs = require('fs');
const path = require('path');

const PUB_KEY = fs.readFileSync(path.join(__dirname, '../../private/public.key'), 'utf8');

const authenticateJWT = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    const token = authHeader.split(' ')[1];

    jwt.verify(token, PUB_KEY, { algorithms: ['RS256'] }, (err, user) => {
      if (err) return res.sendStatus(403);
      req.user = user;
      next();
    });
  } else {
    res.sendStatus(401);
  }
};

module.exports = { authenticateJWT };

auth.js

const express = require('express');
const router = express.Router();
const { login } = require('../auth/authService');
const jwt = require('jsonwebtoken');
const { issueJWT } = require('../auth/tokenManager');
const fs = require('fs');
const path = require('path');

const PUB_KEY = fs.readFileSync(path.join(__dirname, '../../private/public.key'), 'utf8');

// Endpoint per il login
router.post('/login', (req, res) => {
  const { username, password } = req.body;

  try {
    const { token, expires, refreshToken } = login(username, password); // Aggiunto refreshToken
    res.json({
      success: true,
      token: token,
      expiresIn: expires,
      refreshToken: refreshToken // Inviato il refreshToken nella risposta
    });
  } catch (error) {
    res.status(401).json({ success: false, message: error.message });
  }
});

// Endpoint per il rinnovo del token
router.post('/refreshToken', (req, res) => {
  const { refreshToken } = req.body;

  if (!refreshToken) {
    return res.status(401).json({ message: "Refresh Token richiesto" });
  }

  try {
    const payload = jwt.verify(refreshToken, PUB_KEY, { algorithms: ['RS256'] });

    // Aggiungi qui la logica per verificare che il refresh token sia ancora valido, per esempio controllando nel tuo database

    const user = { id: payload.sub }; // Assumi che tu possa ottenere l'utente in base al sub nel payload
    const newTokenObject = issueJWT(user);
    res.json({
      success: true,
      token: newTokenObject.token,
      expiresIn: newTokenObject.expires
    });

  } catch (error) {
    return res.status(403).json({ message: "Refresh Token non valido" });
  }
});

module.exports = router;

最后在我的 info.js (保护区)

const express = require('express');
const router = express.Router();
const { authenticateJWT } = require('../middleware/authMiddleware');

router.get('/getInfo', authenticateJWT, (req, res) => {
  res.json({ message: 'Protected area' });
});

module.exports = router;
javascript node.js express jwt
1个回答
0
投票

您需要更改代码中的三个部分。

#1 问题JWT()

./src/auth/tokenManager.js

const issueJWT = (user) => {
    const expiresIn = 60; // 60 seconds
    const payload = {
        sub: user.id,
        iat: Date.now(),
        exp: Math.floor(Date.now() / 1000) + expiresIn // exp is in seconds since Unix epoch
    };
    const signedToken = jwt.sign(payload, PRIV_KEY, { algorithm: 'RS256' });
    return {
        token: signedToken,
        expires: expiresIn
    };
};

“承载者”不是 nessaray

来自

    token: "Bearer " + signedToken,

    token: signedToken,

并且

payload.exp
需要从now()开始添加60秒

#2 验证JWT()

./src/middleware/authMiddleware.js

const authenticateJWT = (req, res, next) => {
    const authHeader = req.headers.authorization;
    if (authHeader) {
        const token = authHeader.split(' ')[1];

        const decodedToken = jwt.decode(token, { complete: true });
        const nowInSeconds = Math.floor(Date.now() / 1000); // Convert current time to seconds
        if (decodedToken.payload.exp < nowInSeconds) {
            // Token has expired
            return res.sendStatus(401);
        }

        jwt.verify(token, PUB_KEY, { algorithms: ['RS256'] }, (err, user) => {
            if (err) return res.sendStatus(403);
            req.user = user;
            next();
        });
    } else {
        res.sendStatus(401);
    }
};

'const demodToken = jwt.decode(token, {complete: true });' 可以提取'decodedToken.payload.exp'过期毫秒。所以你必须除以 1000 来换算秒并进行比较。

邮差测试

获取代币URL

POST http://localhost:3000/auth/login

Tests
选项卡中

var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("test-token", jsonData.token);
console.log(pm.environment.get("test-token"));

体内

{
    "username": "test",
    "password": "password"
}

获取用户信息

GET http://localhost:3000/info/getInfo

60秒内调用API

60秒后,调用API

© www.soinside.com 2019 - 2024. All rights reserved.