14

In the express-jwt docs there is a reference to being able to use a getToken function to get the token from a request.

How do you use this call in a route?

app.use(jwt({
  secret: 'hello world !',
  credentialsRequired: false,
  getToken: function fromHeaderOrQuerystring (req) {
    if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
        return req.headers.authorization.split(' ')[1];
    } else if (req.query && req.query.token) {
      return req.query.token;
    }
    return null;
  }
}));
K. Waite
  • 1,574
  • 13
  • 12
Samuel Goldenbaum
  • 18,391
  • 17
  • 66
  • 104
  • 1
    please let us know whether our answers helped solve your problem or point you in the correct direction, as we would like to ensure our answers are constructive and beneficial to users of the community as well as yourself. Thanks! – signus Jun 04 '15 at 09:36

3 Answers3

8

A useful little trick is to add unless which makes every URL except those specified by unless require a token.

This means you don't need to create a app.get for every single path in your api that you want to protect (unless you want different secrets for each, which I don't know why you would).

var jwt = require('jsonwebtoken');
var expressJWT = require('express-jwt');

app.use(
  expressJWT({
    secret: 'hello world !',
    getToken: function fromHeaderOrQueryString (req) {
        if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer')
            return req.headers.authorization.split(' ')[1];
        else if (req.query && req.query.token)
            return req.query.token;

        return null;
    }
  }).unless({ path: ['/login'] }));

// Test paths
app.get('/login', function (req, res) {
   res.send("Attempting to login.");
});

app.get('/otherurl', function (req, res) {
    res.send('Cannot get here.');
});

Or you simply specify it for a single path:

app.get('/protected',
   expressJWT({
     secret: 'hello world !',
     getToken: function fromHeaderOrQueryString (req) {
        if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer')
            return req.headers.authorization.split(' ')[1];
        else if (req.query && req.query.token)
            return req.query.token;

        return null;
      }
 }));

Notice the change from get and use in the configuration.

For every path that you supply through express-jwt, the function getToken is run if specified in your configuration.

What's nice about adding unless is that now you have minimized the amount of work you need to do in order to get the token from the user for each and every path.

Refer to index.js of express-jwt which tells you more about how getToken works:

  • If you specify the option as a function, the token value is the returned value of the function
    • This means that you can supply custom logic for handling your tokens, and may be a useful place to call verify.
  • Otherwise it runs the standard logic for extracting the token from the Authorization header with the format of '[Authorization Bearer] [token]' (I denote the brackets to show where it splits the string).
signus
  • 1,118
  • 14
  • 43
2

Like so:

app.get('/protected',
  jwt({
    secret: 'hello world !',
    credentialsRequired: false,
    getToken: function fromHeaderOrQuerystring(req) {
      if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
        return req.headers.authorization.split(' ')[1];
      } else if (req.query && req.query.token) {
        return req.query.token;
      }
      return null;
    }
  })
);

Just add the getToken field in the object you pass to the jwt middleware. It's a combination of the example in the question, and the first example in the documentation.

Amin Shah Gilani
  • 8,675
  • 5
  • 37
  • 79
0

Another way to get a JWT and Bearer tokens is:

To get a JWT token

let token = req.headers.authorization && req.headers.authorization.match(/^JWT (.*)$/);
if (token && token[1]) { token = token[1]; }
if (!token) { throw ['missingRequired']; }

To get a Bearer token

let token = req.headers.authorization && req.headers.authorization.match(/^Bearer (.*)$/);
if (token && token[1]) { token = token[1]; }
if (!token) { throw ['missingRequired']; }

To support both types of tokens:

let token = req.headers.authorization
  && (
    req.headers.authorization.match(/^JWT (.*)$/)
    || 
    req.headers.authorization.match(/^Bearer (.*)$/)
  );
if (token && token[1]) { token = token[1]; }
if (!token) { throw ['missingRequired']; }
HMagdy
  • 3,029
  • 33
  • 54