QA Interview Hub · Knowledge base · Quizzes
API
Authentication and authorization
JWT and testing tokens
A JWT consists of three parts separated by dots: a header (the algorithm and type), a payload (claims: user data, roles, issue and expiry time) and a signature. Each part is encoded in Base64URL, so the payload can be read by anyone: it isn't encrypted. The signature guarantees the token wasn't altered, and the server checks it with a secret or a public key.
Key claims: exp is the expiry time, iat is the issue time, sub is the user identifier. The token is passed in the header Authorization: Bearer <token>. There is usually a short-lived access token and a longer refresh token for getting a new one.
Tests: an expired token must return 401, for which I take an old token or a test environment with a short lifetime. A forged token: I change the role in the payload without re-signing, and the server must reject it because of the invalid signature. I also check the algorithm none, a token from another environment, an empty and a truncated token, as well as token invalidation after logout and a password change.
Authorisation types in Postman
Authorisation is set once at the collection level, and in requests you put Inherit auth from parent. For public endpoints, for example login, No Auth.
| Type | What it looks like in a request |
|---|
| Bearer Token | Authorization: Bearer <token>: the most common, the token is usually a JWT |
| Basic Auth | Authorization: Basic base64(login:password): this is encoding, not encryption |
| API Key | A header (x-api-key: ...) or a query parameter |
| OAuth 2.0 | Postman itself goes through the flow and gets an access token |
| Cookie | A session cookie after login; managed through the Cookies tab |
An important nuance about Basic: base64 is decoded in a second, so without HTTPS the login and password are effectively transmitted in plain text. An API Key in a query parameter is also risky, because the URL ends up in server and proxy logs.
In an interview: Most often it is a Bearer token, usually a JWT, which I set at the collection level, and requests inherit the authorisation. I also know Basic, API Key, OAuth 2.0 and cookie sessions, and I remember that Basic is encoding, not encryption.
The token automatically and what to check
The token automatically. In the post-response script of the POST /auth/login request save the token into a variable, and in the collection specify Bearer {{token}}:
pm.test('Login 200', () => pm.response.to.have.status(200));
const { accessToken } = pm.response.json();
pm.environment.set('token', accessToken);
Now it is enough to run the login once, and all the collection's requests pick up the fresh token. For Runner and Newman the login is put as the first request in the collection, or the token is obtained through pm.sendRequest in the collection's pre-request script.
What to check:
- Without a token: 401.
- A corrupted and an expired token: 401.
- A token after logout: 401.
- Another user's token against someone else's resource: 403 or 404, but never data.
The last one is IDOR, one of the most dangerous bugs in fintech. To check it I need two test users: I create a resource under the first and then access it with the second's token. If the response has someone else's account or transfer, it is a critical defect.
In an interview: I save the token after login with pm.environment.set and use {{token}} at the collection level. Then I check 401 without a token, with an expired and a corrupted one and after logout, as well as IDOR: access to someone else's resource with another user's token.