47

For example I have following Bearer JWT in my header, what's a elegant way to extract the token itself? Basically anything after Bearer. Since this could be in other formats, I don't want to assume it always starts with Bearer. I'm using node-jsonwebtoken and I didn't find such method.

Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9...TJVA95OrM7E20RMHrHDcEfxjoYZgeFONFh7HgQ

ycshao
  • 1,768
  • 4
  • 18
  • 32

13 Answers13

89

For security reasons you should make sure that the Authorization header has the expected content. You simply should not accept a header that does not start with Bearer if you are expecting it ("Bearer" is a recommendation in the RFC, it is not mandatory) ".

if (authHeader.startsWith("Bearer ")){
     token = authHeader.substring(7, authHeader.length);
} else {
   //Error
}
pedrofb
  • 37,271
  • 5
  • 94
  • 142
35

You can split with space using

TokenArray = jwttoken.split(" ");

it will store in an array form where the 2nd index ( 1 as first index is 0) TokenArray[1] will be the token and use

Jwt.decode(TokenArray[1])

to decode the token JWT is a token standard which you can use in many ones and one of the most used case of this is for authorization and it can be done in many ways too but the prefered standard way is sending it in a bearer authorisation header You can userefresh_token instead to bearer token but you have to store the token somewhere which will somehow reduced the effeciency of the term stateless token . So the bearer approch is completly stateless and a prefered approach

Aniketh Saha
  • 843
  • 10
  • 22
  • 10
    Be careful please with decode as it doesn't verify if the token is valid, use verify instead and handle the rejection if it's invalid – Mazen Elkashef Mar 03 '20 at 06:35
15

I wrote a function for extracting the token from the request header or the query. I post it here. Hope it helps someone.

function extractToken (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;
}
Sinandro
  • 2,426
  • 3
  • 21
  • 36
9

For typescript, nodejs, import jwt-decode.

import jwtDecode from 'jwt-decode';

    const authHeader = String(req.headers['authorization'] || '');
    if (authHeader.startsWith('Bearer ')) {
      const token = authHeader.substring(7, authHeader.length);
      const payload = jwtDecode(token) as JwtPayload;
    }

JwtPayload is an interface or a class.

export interface JwtPayload {
  id: string;
  username: string;
  email: string;
  role: string;
  expire: number;
}
Rong Zhuang
  • 121
  • 1
  • 3
6

Simple utility function which returns token

function getToken(req) {
  if (
    req.headers.authorization &&
    req.headers.authorization.split(" ")[0] === "Bearer"
  ) {
    return req.headers.authorization.split(" ")[1];
  } 
  return null;
}

Then the token can be passed to other methods. For example, verifying the signature.


  const token = getToken(req);

  if (!token) {
    throw new Error("Authorization token is required");
  } 
 jwt.verify(token, secret, function (err, decoded) {
    if (err) {
      throw new Error("Error : " + err);
    }
    console.log(decoded);
  });
Tanver Hasan
  • 1,687
  • 13
  • 12
3

since your authorization header is always preceded with "Bearer " you can use try this :

 String token = authorizationHeader.substring("Bearer ".length);

this would return the rest of the content of Authorization header , i hope this would be helpful.

Khaled Awad
  • 1,644
  • 11
  • 24
misterM
  • 71
  • 1
  • 2
2

this is my version for safe and clean code for typescript to parse bearer.

        // parse token bearer
        const tokenBearer = req?.headers?.authorization ? (() => {
            const authHeader = <string>req?.headers?.authorization || ``
            const [code,token] = authHeader.trim().split(` `)
            if (code !== `Bearer`)
                return void 0
            else
                return token
        })() : void 0
FatihAziz
  • 438
  • 4
  • 11
1

You can do something like this in TypeScript which is way cleaner than most of the answers I saw here.

export const parseBearer = (bearer: string) => {
  const [_, token] = bearer.trim().split(" ");
  return token;
};

Basically truncating the bearer string, splitting by space and then getting the element(token) at the index of one.

To handle the token all you will have to do is to verify it using a package such as jsonwebtoken. Final result will look something like this:

import jwt from "jsonwebtoken"

const authorizationHeader = req.headers["Authorization"];
const token = parseBearer(authorizationHeader);

try {
    const decoded = jwt.verify(token, secret);
    return res.json(decoded);
} catch (error: any) {
    return res.status(403).json({ error: "Invalid token" });
}
  • req.headers["authorization"] – Pranu Pranav Mar 16 '22 at 10:54
  • @PranuPranav can you explain your comment please? – ggorlen Oct 15 '22 at 21:19
  • @ggorlen It is the typo in the headers field. – Pranu Pranav Oct 16 '22 at 05:05
  • Are you trying to suggest it should be lowercase? If so, I've always seen it uppercased. Please share some evidence to support your claim. – ggorlen Oct 16 '22 at 05:07
  • I saw it in express request if I console.log({ headers: req.headers }); For your reference a screen shot included: https://ibb.co/gStgQYx – Pranu Pranav Oct 16 '22 at 05:58
  • @PranuPranav you can read [this StackOverflow thread](https://stackoverflow.com/questions/5258977/are-http-headers-case-sensitive) where they more thoroughly discuss the case-sensitive/insensitive parts of the HTTP protocol. Usually, both ways work, however, in Node.js specifically the headers are automatically converted to lowercase. More information about this can be found on the following page: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#method-url-and-headers. My example does not introduce anything that would break one's code, since it is also works. – michaelgrigoryan25 Oct 16 '22 at 14:53
  • @ordinaryduck yes. I just checked the postman request header it is Authorization. in express req.header it is authorization. I am confused. Thanks for sharing this. – Pranu Pranav Oct 17 '22 at 06:03
1

const jwtString = req.headers.authorization.split(' ')[1]

Chinedu Ofor
  • 707
  • 9
  • 11
0

The most universal solution that I came up with (you can adjust 'needle' according to your needs):

const authHeader = 'Bearer mytokengoeshere OtherThing...';
const needle = 'Bearer ';
const bearerAt = authHeader.indexOf(needle);
const spaceAfterTokenAt = authHeader.indexOf(' ', needle.length);
const token = authHeader.slice(
    bearerAt + needle.length,
    spaceAfterTokenAt > -1 ? spaceAfterTokenAt : authHeader.length
);

You can drop spaceAfterTokenAt logic at all in case if you sure that you authorization header would be just as simple as 'Bearer mytokengoeshere' string.

Vlad
  • 985
  • 1
  • 6
  • 10
0

Regular expressions may help.

const header = "Bearer eyJhbGciOiJIUzI1NiIXVCJ9";

const extractedAuth =
  header?.match(/^(?<type>.+?)\s+(?<token>.+?)$/)?.groups ?? {
    type: "none"
  };
console.log(extractedAuth);

// then you can perform your actions like:
switch (extractedAuth.type.toLowerCase()) {
  case "bearer":
    console.log("Auth scheme is Bearer and the token is", extractedAuth.token);
    break;
}
Tolgahan Albayrak
  • 3,118
  • 1
  • 25
  • 28
0
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.replace(/^Bearer\s+/, '');

The regular expression /^Bearer\s+/ matches the Bearer keyword at the beginning of the string followed by one or more whitespace characters. The replace() function removes this pattern from the string, leaving only the JWT token.

This approach is more secure because it ensures that the Authorization header has the expected format (Bearer ), and prevents potential exploits that could occur if an attacker were to manipulate the header value to inject malicious content.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
-1

//When token is String, i saw that have " before and end of string, so i have to remove " from token as below // Add the Authorization header with the AccessToken.

            token = token.Substring(1, token.Length-2);
                client.DefaultRequestHeaders.Authorization =  new AuthenticationHeaderValue("Bearer", token);
              
Truong Mai Van
  • 137
  • 1
  • 4
  • This is pretty odd. Usually strings don't have quotes _literally in_ them on the ends, just as delimiters for purposes of code and display Are you sure your client isn't sending a bad request with extra quotes? Also, the code is broken here. Is this supposed to be JS? – ggorlen Oct 15 '22 at 21:20