我正在使用JWT ("jsonwebtoken": "^5.4.0")
和快递4和玉。
我能够创建正确的令牌,但我如何在每次通话中传递此令牌?
我必须存储此令牌?在标题中还是在localStorage中?
现在我正在使用CURL和Postman,并在标题中设置标记
x-access-token
我是否创建了一个从数据库中检索令牌并在每次调用中使用它的中间件?
感谢
答案 0 :(得分:12)
您无需保存并检查数据库中的令牌。此令牌可以仅使用您的服务器解码此类机制,如果已完成令牌有效。您想要执行的代码应如下所示。
var cookieParser = require('cookie-parser')
app.use(cookieParser())
app.get('/login', function(req, res, next) {
var user = {name:'test'}; //!! find the user and check user from db then
var token = jwt.sign(user, 'secret', {
expiresInMinutes: 1440
});
res.cookie('auth',token);
res.send('ok');
});
app.use(function(req, res, next) {
var token = req.cookies.auth;
// decode token
if (token) {
jwt.verify(token, 'secret', function(err, token_data) {
if (err) {
return res.status(403).send('Error');
} else {
req.user_data = token_data;
next();
}
});
} else {
return res.status(403).send('No token');
}
});
在这里你可以找到非常好的文章:https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
答案 1 :(得分:3)
如果您想要本地存储空间,我建议您先检查一下:https://www.npmjs.com/package/node-localstorage
但是,有了这个说法,你们和女孩们都不会相信我从上面的答案中找到res.cookie('auth' token)
需要多长时间。我花了几个小时搜索Google,Passport文档,Express文档,GraphQL和身份验证/授权文档,试图找出如何以无状态方式将令牌发送到API 。
我已经构建了JWT令牌安全性并使用它保护了我的GraphQL解析器,但是,我选择使用EJS和graphql-request(与Apollo Client大致相同),所以我需要找到一种方法将令牌传递给我的中间件没有使用服务器端会话。
在cookie中存储JWT令牌是很好的,特别是如果您采取额外的预防措施,例如签署cookie,我记得还有一些选项可以保持cookie的安全性,以便其他网站在&#时看不到它34;浏览器"允许访问cookie。如果cookie与您的服务器机密签名,则cookie内的数据根本无法更改并仍然有效。风险始终是有人泄露他们的令牌/ cookie,如果这困扰你,请研究刷新令牌。但是,API令牌通常应该保密并且安全。你最大的烦恼更可能是维持一个JWT黑名单的要求,如果你将到期日期定为1年,那么该名单将在一年后到期。
我只是在这里包括我的发现,因为这个问题实际上是一种罕见的资源......
以下是我的用于身份验证的Express中间件:
// AUTHENTICATION
app.use(async (req) => {
try {
const token = req.headers.authorization || req.cookies.auth
const { person } = await jwt.verify(token, SECRET)
req.person = person
return req.next()
} catch (e) {
return req.next()
}
})
req.person
的形式提供。如果未设置req.person,则将该用户视为未登录。return req.next()
,这一点很重要,因为调用next()
不带参数会被视为"干净的下一个中间件和/或继续处理请求"。如果你包含任何字符串或对象参数,它将抛出一个错误,可以冒泡到你的错误处理中间件。你可以自己试试。将return next('You are not authenticated.')
放入catch块,您将看到它在您的路线前停止请求。return next()
,因为我在路由和解析器中处理授权。它允许更多的灵活性,例如促进非认证用户访问注册和登录突变。这是我的GraphQL端点(我使用的是Apollo Server):
app.use('/graphql', bodyParser.json(), graphqlExpress((req) => {
const context = {
person: req.person
}
return {
schema,
context,
rootValue: null
}
}))
context.person
填充req.person
来自上述身份验证中间件。以下是我使用名为
graphql-request
的NPM包的方法: https://www.npmjs.com/package/graphql-request
app.get('/allpeople', async (req, res) => {
try {
const client = new GraphQLClient(GRAPHQL_ENDPOINT, {
headers: { Authorization: req.headers.authorization || req.cookies.auth }
})
const query = `query allPeople($serialNumber: String!) {
allPeople(serialNumber: $serialNumber) {
id
created
status
email
}
}`
const variables = {
serialNumber: req.person
}
const response = await client.request(query, variables)
res.render('allpeople/list', { people: response.allPeople })
} catch (e) {
throw [`allPeople`, `${JSON.stringify(error, null, 2)}`]
}
})
createNetworkInterface
和new ApolloClient()
。