1

I am trying to write a pre-request script for getting JWT for my postman tests using Laravel. I tried the js code that works perfect when I use .NET REST API, but now in Laravel it is not working. If I hit the login endpoint it works I got my JWT, and the response look like this:

{
  "status_code": 200,
  "access_token": "15|we59pMz1wA6TqwALTJg9IT8pNs3mc4Omwibm7Lkd",
  "token_type": "Bearer"
}

Here is my pre-request JS script:

const requestBody =
{
    "Email" : "username",
    "Password" : "password"
}

pm.sendRequest
({
    url: 'http://localhost:8000/api/login',
    method: 'POST',
    header:
    {
        'content-type': 'application/json'
    },
    body:
    {
        mode: 'raw',
        raw: requestBody    
    }
}, function (err, res)
{
    if(err)
    {
        console.log("Login failed:");
        console.log(JSON.stringify(err));
        return;
    }
    else
    {          

    const response = res.json();   
    const token = 'Bearer ' + response.access_token;
    pm.environment.set("TOKEN", token);

        console.log("Login succeeded!");
    }
});

The response in pre-request is this:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='http://localhost:8000'" />

        <title>Redirecting to http://localhost:8000</title>
    </head>
    <body>
        Redirecting to <a href="http://localhost:8000">http://localhost:8000</a>.
    </body>
</html>
Wasyster
  • 2,279
  • 4
  • 26
  • 58

1 Answers1

0

Your token doesn't seem like a JWT.

This is not base64 and does not contain the 3 parts: header, payload, signature.

Don't hesitate to look at my Postman pre request gist for JWT there are some explanations here too.

It contains one function to check the token validity:

/** Checks if the JWT is present and not expired
The token is expected to be found in `token` environment variable
*/
function isValidToken() {
    const token = pm.environment.get("token");
    if (!token) {
        console.log("Token is missing");
        return false;
    }
    // Payload is retrieved by
    // JSON parsing the base64 decoded `atob()` 2nd part of the JWT `[1]`
    // (1st is the header, 3rd is the signature)
    const payload = JSON.parse(atob(token.split('.')[1]));
    // Expiration timestamp (in seconds) is located in the `exp` key
    const millisecBeforeExpiration = (payload.exp * 1000) - (new Date()).getTime();
    if (millisecBeforeExpiration <= 0) {
        console.log("Token is expired");
        return false;
    }
    console.log("Token is valid",
        `will expire in ${millisecBeforeExpiration / 1000} seconds`);

    return true;
}

and one to get a new token

/** Gets a new JWT
This can be entirely custom authentication.
Here we rely on `user`/`pass` environment variables.
`host` also needs to be set, feel free to use another route instead of /give-me-a-jwt :)
*/
function login() {
    const body = JSON.stringify({
        "user": pm.collectionVariables.get("user"),
        "pass": pm.collectionVariables.get("pass")
    });
    const request = {
        url: pm.collectionVariables.get("host") + "/give-me-a-jwt",
        method: "POST",
        header: {
            "Content-Type": "application/json",
            "Accept": "application/json",
        },
        body,
    };

    pm.sendRequest(request, (err, res) => {
        if (res.code !== 200) throw new Error(res.status);
        console.log("Token refreshed");
        pm.environment.set("token", res.json().token);
    });
}

Now you can just get a new token if not valid:

if (!isValidToken()) login();

Of course don't forget to use your brand new token in your Postman's Bearer Token authentication type

Pierre de LESPINAY
  • 44,700
  • 57
  • 210
  • 307