API Authentication and Authorization with Cypress

Kishor Munot
6 min readSep 13, 2024

--

Authentication and Authorization

Hello Readers,

Authentication and Authorization these two keyword are very important in human’s life. Every human Authenticate and Authorize action before taking his action. In API testing also we Authenticate and Authorize the API to save our business needs.If you landed on this blog post, chances are that you care about keeping your API secure. It’s an important topic to discuss: API exploits are on the rise, and you don’t want unauthorized users accessing your data. A big part of that security is implementing API authentication and API authorization. These API access control measures are a foundational aspect of API security.

Authorization and Authentication

It’s easy to confuse API authentication and API authorization. You may know that both help ensure that the right people access the right data, but what’s the difference between the two? And why should you care about enforcing both of them?

Here’s one way to think of it: imagine your API was a library, and your sensitive data was a rare first-edition book. The API authentication would check each potential borrower’s government ID to make sure they’re really the person they claim to be. Once their identity was proven to be authentic, the API authorization would check their library card to see if they’re allowed to access the section with rare books.

Authentication and authorization work together to keep your API secure. In the previous example, a borrower might have proven their identity, but may not have access to the restricted section from which the rare book came. So authentication may prove successful, but authorization may still prevent borrowing that book. In the same way, you can use authentication and authorization together to make sure the right people access the right data using your API.

Most Used API Authentication Methods

So API authentication is critical, but how can you start implementing it?

The first step is choosing an authentication method. There are multiple authentication methods available, and different methods are appropriate for different situations. Understanding the differences can help you select the best method for you. Here are four of the most popular API authentication methods used to secure the APIs of countless organizations.

Basic authentication

Basic HTTP authentication is the simplest method of API authentication. It involves adding a username and password to the request in every API call.

Token Authentication

Token authentication is also known as bearer authentication. To use it, you just specify Authorization: Bearer <token>, where the token is a string that represents the user’s identity and permissions. If you have (bear) the token, you can get the appropriate access to the API.

OAuth authentication

OAuth is an open authorization framework that uses a type of token authentication, but it leverages credentials from one service provider to log into other service providers.

API key authentication

API keys are also way more secure than basic authentication and grant access via a string of text, but they are different from token authentication in one crucial aspect.

While token authentication proves who the user is that’s accessing the API, it doesn’t identify the application making the request. APIs are the opposite of this: they provide info about the application making the request, but they don’t supply user-specific information.

Most Used API Authentication in Cypress

Let’s start by understanding what Basic Authentication is. Basic Authentication is a simple authentication scheme built into the HTTP protocol. It involves sending the username and password encoded in Base64 as part of the request headers. Its simplicity, widespread support, and stateless nature make it an attractive option for many scenarios, particularly during development and testing. A basic auth modal looks like this.

One of the simplest ways to handle Basic Authentication in Cypress is by embedding the credentials directly in the URL when visiting the protected page. This method involves embedding the username and password directly in the URL that you visit. While it’s less secure due to the exposure of credentials in the URL, it can be convenient for testing purposes.

Below is the example on how to use above format:

describe('Basic Auth Test with URL Embedding', () => {
it('should successfully authenticate using embedded credentials', () => {
const username = 'yourUsername';
const password = 'yourPassword';
const url = `https://${username}:${password}@example.com`;

cy.visit(url);

// Add your tests here
});
});

It’s a quick and simple way to handle Basic Authentication, but it’s less secure and generally not recommended for production environments.

Store the credentials in the Cypress configuration file and access them via Cypress.config() to use them to send them by using auth option in the cy.visit() function or by constructing the URL dynamically. This prevents hardcoding credentials in your test files.

// cypress.json
{
"username": "yourUsername",
"password": "yourPassword"
}
____________________________________________
// Test file Method 1
cy.visit('https://example.com', {
auth: {
username: Cypress.config('username'),
password: Cypress.config('password')
}
});
____________________________________________
// Test file Method 2
const username = Cypress.config('username');
const password = Cypress.config('password');
const url = `https://${username}:${password}@example.com`;

cy.visit(url);

After basic authentication there is Auth 2.0 is very popular these days and now we will try to handle this with the cypress.

At the most basic level, before OAuth 2.0 can be used, the Client must acquire its own credentials, a _client id _ and client secret, from the Authorization Server in order to identify and authenticate itself when requesting an Access Token.

Using OAuth 2.0, access requests are initiated by the Client, e.g., a mobile app, website, smart TV app, desktop application, etc. The token request, exchange, and response follow this general flow:

  1. The Client requests authorization (authorization request) from the Authorization server, supplying the client id and secret to as identification; it also provides the scopes and an endpoint URI (redirect URI) to send the Access Token or the Authorization Code to.
  2. The Authorization server authenticates the Client and verifies that the requested scopes are permitted.
  3. The Resource owner interacts with the Authorization server to grant access.
  4. The Authorization server redirects back to the Client with either an Authorization Code or Access Token, depending on the grant type, as it will be explained in the next section. A Refresh Token may also be returned.
  5. With the Access Token, the Client requests access to the resource from the Resource server.

Now we are going to see that how can we handle au

describe('How to use OAuth in Cypress', () => {
describe('Oauth feature apis', ()=>{
let access_token = '';
let userId = ''

beforeEach('generate token', ()=>{
//to get the token id(access token)
cy.request({
method: 'POST',
url: '/token',
form: true,
body:{
"client_id" : "CyPressApp",
"client_secret" : "f0590fba402263485300ed0b4612217d",
"grant_type" : "client_credentials"
}
}).then(response=>{
cy.log(JSON.stringify(response));
cy.log(response.body.access_token);
access_token = response.body.access_token;

//get the user id
cy.request({
method: 'GET',
url: '/api/me',
headers: {
'Authorization' : 'Bearer ' + access_token
}
}).then(response=>{
userId = response.body.id;
cy.log("user id " + userId);
})
})
})
it('Unlock the Barn Test', ()=>{
cy.request({
method: 'POST',
url: '/api/'+userId+'/barn-unlock',
headers: {
'Authorization' : 'Bearer ' + access_token
}
}).then(response=>{
cy.log(JSON.stringify(response));
expect(response.status).to.equal(200);
})
})


it('Put the Toilet Seat Down Test', ()=>{
cy.request({
method: 'POST',
url: '/api/'+userId+'/toiletseat-down',
headers: {
'Authorization' : 'Bearer ' + access_token
}
}).then(response=>{
cy.log(JSON.stringify(response));
expect(response.status).to.equal(200);
})
})

it('Chicekn Feed Test', ()=>{
cy.request({
method: 'POST',
url: '/api/'+userId+'/chickens-feed',
headers: {
'Authorization' : 'Bearer ' + access_token
}
}).then(response=>{
cy.log(JSON.stringify(response));
expect(response.status).to.equal(200);
})

})

})

In above code I am generating the token which need to use OAuth so I have execuated Post API with “client_id, “client_secret” , “grant_type”. We need to fetch the response and then store the access token and use in the various API’s.

// cypress/support/commands.js
Cypress.Commands.add('loginByToken', (token) => {
// Set up the token in local storage or cookies
cy.setCookie('auth_token', token);
});

// Optionally, you might need to handle headers or other details
Cypress.Commands.add('setAuthHeader', (token) => {
cy.intercept('GET', '**/api/**', (req) => {
req.headers['Authorization'] = `Bearer ${token}`;
});
});

You can mock the response with cy. intercept and fetch the token and use.

Please share your valuable feedback in the comments below.

Here to make the community stronger by sharing our knowledge. Let me know your feedback into the comments so we can learn together.

Thank you,

Happy Testing.

--

--