检查标题值是否匹配

时间:2020-05-27 18:57:42

标签: javascript node.js express

是否可以检查Node.js中的标头值?我想创建一个仅当用户提供标题并且其值与编码内容匹配时才可以访问的路由。例如,假设路由期望一个像AccessKey: 12345这样的标头,因此它检查是否存在包含该值的标头,如果不匹配则抛出错误。我试图使用类似res.hasHeader()这样的东西:

app.route('/rest/api/here').get((req, res) => {
    if (res.hasHeader('AccessKey', '12345')){
          res.send('test') 
      } else {
          res.send('Header value doesn\'t match')
      }
    })

,但它仅检查标头是否存在并且不检查值是否匹配。申请主要是出于教育目的,因此,如果可能的话,这种方法是可以接受的。

1 个答案:

答案 0 :(得分:1)

我建议使用库来解析结果,这是一个带有注释的完整示例,以解释各部分。正如@Heretic Monkey指出的那样,令牌位于请求对象上,但这不是我将使用的方法。

// this is standard set of imports in app generated by
// express --no-view
// from package npm i -g express-generator
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

// token 'parsing' library
var bearer = require('express-bearer-token');

// more boilerplate
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// look for the key in headers: { Authorization: AccessKey <your key> }
// this library also has options for query, body, etc... 
// https://www.npmjs.com/package/express-bearer-token
app.use(bearer({ headerKey: 'AccessKey' }));

// if present and what you wanted, proceed, else, fail
var protect = (req, res, next) => (
  (req.token && req.token === '12345')
    ? next()
    : next(new Error('bad token'))
);

// example protected (can protect a whole router with router.use(protect))
app.get('/protected', protect, (r, s) => s.json({ data: 'api' }));

// example not protected
app.get('/example', (r, s) => s.json({ not: 'protected' }));

// make sure to status 500 to make axios client throw
app.use((error, r, s, n) => s
  .status(500)
  .json({ error: (error + '') }));

// run the server
var server = app.listen(3000);

// client code (axios works in browser same exact api)
var axios = require('axios');

// wait until server started
setTimeout(async function() {
  // you will get status 500 without key on protected route
  try {
    await axios.get('http://localhost:3000/protected');
    console.log('nope, wont see me print')
  } catch (e) {
    console.log('error for protected no token:', e.response.data.error);
  }

  // non protected works as expected
  var example = await axios.get('http://localhost:3000/example');
  console.log('got example data fine: ', example.data);

  // for protected, need to supply header
  var protected = await axios({
    method: 'get',
    url: 'http://localhost:3000/protected',
    headers: { Authorization: 'AccessKey 12345' }
  });
  console.log('got protected data fine w/tok: ', protected.data);

  // wait for server to shut down then exit the program
  server.close(() => console.log('bye'))
}, 500);