vignesh
vignesh

Reputation: 3

Creating own http request instead of using googleapis and axios in k6 to get access token

I have been using k6 to load test a web application where I need to access gmail inbox for parsing. As googleapis and axios are not supported in k6 I created http requests using k6/http module. I was able to retrieve the access token but couldn't access the mail inbox. Struck with this error

INFO[0001] {"error":{"code":401,"message":"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.","errors":\[{"message":"Login Required.","domain":"global","reason":"required","location":"Authorization","locationType":"header"}],"status":"UNAUTHENTICATED","details":[{"domain":"googleapis.com","metadata":{"service":"gmail.googleapis.com","method":"caribou.api.proto.MailboxService.ListMessages"},"@type":"type.googleapis.com/google.rpc.ErrorInfo","reason":"CREDENTIALS_MISSING"}]}}

This is the manually written access token retrieval part

const payload = `client_id=${clientId}&client_secret=${clientSecret}&refresh_token=${refreshToken}&grant_type=refresh_token`;
  
  const tokenResponse = http.post(tokenUrl, payload, {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  });
  
  const accessToken = tokenResponse.json().access_token;

It logged the accestoken in the console

const options = {
      url: 'https://gmail.googleapis.com/gmail/v1/users/[email protected]/messages',
      params: {
        q: `from:[email protected] to:${profilesEmailAddress}`,
      },
      headers: {
        Authorization: `Bearer ${accessToken.access_token}`,
      },
    };
    const response = http.get(options.url, options.params, options.headers);

This is used to access the gmail inbox where I used http.get() instead of axios(). It couldn't access the mail inbox and returns the error mentioned above. Can someone help me with this? What am I doing wrong? Why it isn't able to access the mail body? I was able to get a response in Postman with the same logic cURL command.

curl -X GET \
  'https://gmail.googleapis.com/gmail/v1/users/[email protected]/messages?q=from%3Ano-reply%40rework.link%20to%[email protected]' \
  -H 'Authorization: Bearer <access_token>'

Thanks.

Upvotes: 0

Views: 172

Answers (2)

vignesh
vignesh

Reputation: 3

Thanks for the heads-up. Its actually working now, I did little changes to the http.get() method as it accepts only two parameters inside the method, I referred from the documentation.

    const options = {
      url: 'https://gmail.googleapis.com/gmail/v1/users/[email protected]/messages',
      params: {
        // q: `from:[email protected] to:${profilesEmailAddress}`,
      // },
        headers: {
          Authorization: `Bearer ${accessToken.access_token}`,
        },
      }
    };
    const response = await http.get('https://gmail.googleapis.com/gmail/v1/users/[email protected]/messages?q=from:[email protected]%20to:[email protected]', options.params);

I inserted the query to the link to get the specified mail.

Upvotes: 0

knittl
knittl

Reputation: 265717

It looks like you are accessing your access token incorrectly: you try to access a non-existent property of a string (accessToken.access_token). accessToken already is the token, not an object. Can you log the value of options.headers.Authorization and does it match your expected value?

Additionally, you are not passing the headers correctly, they must be passed as property of the options argument ({ headers: { … } }), but you are passing an options argument without a headers key, passing the headers themselves as options ({ … }).

The following fixed and simplified code should work:

const payload = `client_id=${clientId}&client_secret=${clientSecret}&refresh_token=${refreshToken}&grant_type=refresh_token`;
  
const tokenResponse = http.post(tokenUrl, {
  client_id: clientId,
  client_secret: clientSecret,
  refresh_token: refreshToken,
  grant_type: 'refresh_token',
});
  
const accessToken = tokenResponse.json('access_token');

const response = http.get(
  'https://gmail.googleapis.com/gmail/v1/users/[email protected]/messages',
  { q: `from:[email protected] to:${profilesEmailAddress}` },
  {
    headers: {
      authorization: `bearer ${accessToken}`,
    }
  });

Upvotes: 0

Related Questions