Проверить соответствие значения заголовка - PullRequest
1 голос
/ 27 мая 2020

Можно ли проверить значение заголовка в 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 Ответ

1 голос
/ 28 мая 2020

Я бы порекомендовал использовать библиотеку для анализа результата, вот полный пример с комментариями, поясняющими детали. Как указал @ Hereti c 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...