使用jwt-webtoken和request消费远程API

时间:2018-08-07 21:26:17

标签: node.js jwt node-request

我已根据以下示例创建了一个api:https://github.com/eXtremeXR/APIAuthenticationWithNode(我使用mysql除外)。通过邮递员进行测试时,一切正常。

现在...我想知道其他人如何正确使用/使用此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有效。处理这种情况的最佳方法是什么……有效令牌的持续时间,登录时间……?

3 个答案:

答案 0 :(得分:2)

1)获得令牌后,应根据业务逻辑将其保存到内存,REDIS,会话等中。之后,调用另一个API时,您可以从保存的位置取回它。

例如

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

  • 如果您的应用程序使用它来调用其他服务,则每个请求都使用相同的令牌,您可以将其保存到内存中: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));
});

希望这会有所帮助。

答案 1 :(得分:1)

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

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选项(以避免进行日计算)。

如果要验证令牌是否已过期,唯一的方法是在服务器端对其进行验证。

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

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

答案 2 :(得分:0)

如果我的理解正确,您的第一个请求将从您的服务器获取一个令牌,然后您将该令牌用于第二个请求,以搜索彼得,并且您希望合并这些请求。

standard practice用于将请求与您的请求分开,所以我建议不要将它们组合在一起。

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