使用 jwt-web 令牌和请求使用远程 api

Consume remote api with jwt-webtoken & request

我按照这个例子创建了一个 api:https://github.com/eXtremeXR/APIAuthenticationWithNode(除了我使用 mysql)。当我通过邮递员对其进行测试时,一切正常。

现在...我想知道其他人如何正确地use/consume这个api。我到目前为止是:

所以我有两个请求...第一个获取令牌:

第一个请求

const request = require("request");

request.post({
    headers: { "content-type": "application/json" },
    url: "http://127.0.0.1:2001/abc/login",
    body: JSON.stringify({
        email: "test@abc.it",
        password: "sisw9234&"
    })
}, (error, response, body) => {
    if(error) {
        return console.dir(error);
    }
    console.log(JSON.parse(body).token);
});

...第二个...当我用实际令牌替换 myToken 时...为我提供了请求的 json:

第二次请求

const request = require("request");

var token = 'myToken';
var auth = 'Bearer '+token;

request.get({
    headers: {
        "authorization": auth
    },  
    url: "http://127.0.0.1:2001/abc/search?name=peter"
}, (error, response, body) => {
    if(error) {
        return console.dir(error);
    }
    console.log(JSON.parse(body));
});

如何正确组合它们?

此外...该令牌目前仅对 360s 有效。处理这种情况的最佳方法是什么...有效令牌的持续时间、登录...?

如果我理解正确的话,您的第一个请求会从您的服务器获取一个令牌,然后您在第二个请求中使用该令牌来搜索 peter,并且您希望合并这些请求。

对于这种事情,standard practice 将请求分开,所以我建议不要合并它们。

关于令牌仅在360s内有效,我假设你可以访问服务器代码,因为你正在向本地主机发送请求,所以你需要在那里修改令牌的到期时间。

1) 拿到token后,根据自己的业务逻辑存入内存、REDIS、session……。之后再调用另一个API,就可以从保存的地方取回来

例如,

  • 如果令牌与每个用户相关,则应将其保存到会话中。使用快速服务器,您可以使用 npm install express-session.

  • 如果用于你的应用调用其他服务,每次请求使用相同的token,你可以保存到内存中:global.GLOBAL_TOKEN = response.token

  • 如果你运行多实例,那么你需要将它保存在像REDIS这样的分布式缓存上

2)关于令牌过期,OAuth的最佳实践是当你登录时,服务器总是响应一个令牌(长期令牌,刷新令牌或任何你称之为的)。您可以使用该刷新令牌获取新令牌。

如果您没有那种令牌,您需要像保存令牌一样保存用户名和密码,以便再次登录以获取新令牌。

关于检查过期令牌。您可以使用 JWT.decode,它不需要密码来解码。通过这样做,您可以获得令牌过期的时间。检查的关键通常是 expiat.

有关 JWT 的更多信息,请参阅 https://jwt.io/

快速会话示例

app.use(session({ secret: 'some-secret-here', cookie: { maxAge: 60000 }}))

// login endpoint
app.post('/login', (req, res) => {
    request.post({
        headers: { "content-type": "application/json" },
        url: "http://127.0.0.1:2001/abc/login",
        body: JSON.stringify({
            email: req.body.email,
            password: req.body.password
        })
    }, (error, response, body) => {
        if(error) {
             res.write('login failed');
             return res.end();
        }
        // save token to session
        req.session.token = JSON.parse(body).token;
        res.write('login success');
        return res.end();
    });
});

// endpoint need token endpoint
app.get('something', (req, res) => {
    // use token to call the other things here 
    var token = req.session.token;
    res.write('your token ' + token);
    return res.end();
});

在客户端使用 localStorage 的示例:

const request = require("request");

request.post({
    headers: { "content-type": "application/json" },
    url: "http://127.0.0.1:2001/abc/login",
    body: JSON.stringify({
        email: "test@abc.it",
        password: "sisw9234&"
    })
}, (error, response, body) => {
    if(error) {
        return console.dir(error);
    }
    var token = JSON.parse(body).token;
    localStorage.setItem("USER_TOKEN", token);
});

第二次请求

const request = require("request");

var token = localStorage.getItem('USER_TOKEN');
var auth = 'Bearer '+token;

request.get({
    headers: {
        "authorization": auth
    },  
    url: "http://127.0.0.1:2001/abc/search?name=peter"
}, (error, response, body) => {
    if(error) {
        return console.dir(error);
    }
    console.log(JSON.parse(body));
});

希望这对您有所帮助。

我认为令牌没有在后端正确签名。

JWT.sign的正确用法是

jwt.sign(payload, secretOrPrivateKey, [options, callback])

signToken = user => {
  return JWT.sign({
    iss: 'CodeWorkr',
    sub: user.id,
    iat: new Date().getTime(), // current time
    // exp: new Date().setDate(new Date().getDate() + 1) // current time +     1 day ahead
  }, JWT_SECRET, {
     expiresIn: 3600 // 1 hr = 3600s
  });
}

如您所见,您应该在 JWT_SECRET 之后传递 expiresIn 选项,而不是在负载中的 exp 之后传递(以避免计算天数)。

如果要验证token是否过期,只能在服务端验证。

要再次使用此令牌,您需要将其保存到 localStorage 并在需要时使用。

localStorage.setItem('token', token)
const token = localStorage.getItem('token') // use this token