将令牌保存在使用节点的本地存储中

我使用JWT ("jsonwebtoken": "^5.4.0")和express 4和jade。 我能够创build正确的令牌,但是如何在每次调用中传递此令牌? 在哪里我必须存储这个令牌? 在标题或在localStorage?

现在我用邮递员使用CURL,并在头中设置令牌

 x-access-token 

我是否创build了一个从数据库中检索令牌的中间件,并在每个调用中使用它?

谢谢

您不需要保存并检查数据库中的令牌。 这种令牌机制只能通过你的服务器解码,如果这个令牌是有效的。 你想要做的代码应该看起来像。

 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'); } }); 

在这里你可以find非常好的文章: https : //scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens

我build议检查一下,如果你想本地存储: https : //www.npmjs.com/package/node-localstorage

但是,就这样说,你们和女孩们不会相信从上面的答案中findres.cookie('auth' token)多久了。 我search了几个小时的Google,Passport文档,Express文档,GraphQL和authentication/授权文档,努力了解如何以无状态的方式将令牌传递给API。

我已经构build了JWT令牌安全性并使用它来保护我的GraphQLparsing器,但是之后我select使用EJS以及graphql-request(与Apollo客户端大致相同),所以我需要find一种方法将令牌传递给我的中间件使用服务器端会话。

在Cookie中存储JWT令牌是很好的,特别是如果您采取额外的预防措施(例如对cookie进行签名),我记得还有一些选项可以让cookie保持安全,以便其他站点在“浏览器”允许访问时无法看到到cookies。 如果一个cookie与您的服务器密码签名,cookie内的数据根本无法更改,仍然有效。 风险总是有人泄漏他们的标记/ cookie,如果这困扰你,研究刷新令牌。 但是,API令牌通常应该保密并且安全。 如果您设置过期时间为1年,那么您最大的烦恼将更有可能成为维持一年后即将到期的智威汤逊黑名单的要求。

我只是在这里包括我的发现,因为这个问题实际上是一个罕见的资源,似乎…

这是我的Express中间件authentication:

  // 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() } }) 
  1. 你可以看到我设置cookie的标题作为后备的标记。 这支持我的需求,并允许我真正使用任何具有无状态安全性的客户端。
  2. 我的login用户在我的视图和GraphQLparsing器中可用作req.person。 如果没有设置req.person,则用户被视为未login。
  3. 我正在使用return req.next() ,这很重要,因为不带参数的next()被视为“干净转到下一个中​​间件和/或继续处理请求”。 如果包含任何string或对象参数,将会抛出一个错误,可能会导致error handling中间件。 你可以自己尝试一下。 在catch块中放入return next('You are not authenticated.') ,你会看到它在你的路由之前停止请求。
  4. 我使用return next()因为我处理路由和parsing器中的授权。 它允许更多的灵活性,例如便于注册和login突变被未经authentication的用户访问。

这是我的GraphQL端点(我正在使用阿波罗服务器):

  app.use('/graphql', bodyParser.json(), graphqlExpress((req) => { const context = { person: req.person } return { schema, context, rootValue: null } })) 
  1. 在我的GraphQLparsing器中,每个查询的第三个参数都有context.person ,其中填充了来自上述Authentication中间件的req.person
  2. 那真是一个人需要知道的。

以下是我如何使用名为graphql-request的NPM包: https : 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)}`] } }) 
  1. 我包含了这个代码,因为没有“更高级”的graphql-request的例子用法,我喜欢它。 如果你冒险进入React.js,它非常简洁,可以很容易地换成Apollo客户端。 我的例子对于研究createNetworkInterfacenew ApolloClient()人来说也是非常相关的。