使用 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
,它不需要密码来解码。通过这样做,您可以获得令牌过期的时间。检查的关键通常是 exp
或 iat
.
有关 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
我按照这个例子创建了一个 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
,它不需要密码来解码。通过这样做,您可以获得令牌过期的时间。检查的关键通常是 exp
或 iat
.
有关 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