Authorization and Authentication in React JS | Desuvit

The authorization is a process utilized in an app that helps in controlling the informational access and limiting actions performed by users. Similarly, authentication is a process to check if the user is allowed to access the information or perform any action. If an authenticated user is using your app, they have identified their true identity through several ways, such as providing the right credentials.

Although authentication will help you know the true identity of a user, it can’t help you control access, which is why we utilize authorization with authentication. Without one of these two, havoc can be created in your app. For instance, any user can change the password of another or delete data posted by another user.

We can achieve authentication in ReactJS in the following ways:

  • Cookie-Based authentication
  • Token-Based authentication
  • Third-party access(OAuth, API-token)
  • OpenId
  • SAML

In this article, we will utilize token-based authentication or JWT token in ReactJS for authentication and authorization. Read on to know how that works.

More About JWT Token

In many resources, we need to restrict access to ensure that no user is able to hinder the activity of the other user. Therefore, we utilize IDs and passwords for secure access and authentication. However, the issue here is that HTTP API can’t know if two different requests were raised by one user or not, as HTTP is stateless.

While we can just ask the user to offer ID and password on every API call but that would also mean poor user experience. What we need instead is the ability to request authentication once and identify the user through other ways during subsequent requests. An efficient system that we have for this activity is JSON Web Token which is commonly known as JWT.

JWT token is an open standard (RFC 7519) that offers a self-contained method to transmit information to different parties in a secure way. Since this information is digitally signed, it is trusted and verified.

JWT token is generated whenever a user logs in. This is accessible for one account associated with one user. The user can use this token to utilize their access until they log out.

Structure of JWT Token

Usually, you will find the JWT in the HTTP request header as Authorization key using the Bearer schema.

With the JWT token, you can find three strings that are separated using a period. These base 64 encoded strings are header, payload, and signature. It would look like xxxxxx.yyyyyy.zzzzzz

Below we have decoded these strings for a clear understanding of the JWT structure.

Header

The first part before the period is a header, which contains meta-information or data of the token or JWT. This contains two parts: token type and signing algorithm which is encoded in Base64 to form the first part of the token.

Example:

{
"alg":"SHA256",
"typ":"JWT"
}

Payload

Payload is the second section of your token, which has claims. These are statements that contain an entity or extra data related to the user.

We can add different claims in our token, here are the three types:

  • Registered claims are predefined and they are not really mandatory but it is recommended to use these. For example, audience (aud), expiration time (exp), etc. Since JWT is compact, you will find names of claims consisting of only three characters.
  • When defining public claims, we need to eliminate collision, for which you can define public claims via URI (Containing namespace that is collision-resistant) or IANA JSON Web Token Registry.
  • It is through private claims that we share data between two parties that have agreed to utilize these claims. These are nor public neither registered claims.

The security of the payload is weak, as any person can decode the JWT and see the contents of the payload without much hassle. For this reason, we should not put any sensitive and secret information in the payload. If at all needed, encrypt the data before adding to payload. The payload looks like this:

{
"jti": "359a2088-2276-48c3-8375-378802e039af",
"iat": 1617631282,
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "1413f2f2-5214-413f-8b12-d09cb9a8fa7b",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Admin",
"nbf": 1617631282,
"exp": 1712239282,
"iss": "MyProject",
"aud": "https://www.desuvit.com/"
}

Although the payload is the sole identifying factor for user identification, it doesn’t authenticate the user. Any user with a little knowledge can find the information and create a fake token in this case. Therefore, we utilize signature, which is the key authenticating factor in the JWT to make sure the information is not changed along its way.

Hashing Algorithm

But, before we jump to the signature, let’s see the hashing algorithm.

With the help of a hashing algorithm, we can convert any string to a hash function. For instance, Hello, world can be converted to hash through the SHA265 algorithm. These algorithms have an important property, which doesn’t allow you to find out the original string with the help of the hash that you have.

This is to say that if you have converted Hello, world to hash, then you can’t use that hash to find the string Hello, world.

JWT Signature

In the JWT signature, we utilize three things:

Firstly, the name of the algorithm, such as HMACSHA256, which is derived from the SHA265.

Secondly, the encoded header and payload strings are converted to a hash.

Lastly, a secret key is used that is known to the server only. It contains arbitrary data that we can’t decode.

The reason we encode or use hash for the entire JWT, including payload and header, is to ensure the unique nature of the signature for one specific token.

Rest API for generating the JWT token

Generally in a ReactJS application, we use the Rest API to get the data or save the data. Even for login the user, we use the API endpoint. For the rest of the blog, we assume that the API endpoint would return the JWT after the user is authenticated. This JWT token we would use for any subsequent requests.

Authentication with Rest API

Till now, we have understood the JWT and its structure. How will we use it in the authentication process of our API?

Let’s find out:-

Logging In

  • Whenever a user logs in by providing the credentials which would generally be username and password to a Rest API endpoint, a JWT token would be generated on the server and sent back to the client.
  • Once the client receives the token, they can use it for any future request in order to identify the user with proper authentication.
  • The JWT token which we are going to get from the API, we are going to store it in the session for further use when we need it. The code for calling the API and storing the token in session storage would look as below. In this approach, we are using the redux saga.
export function* loginFlow() {
  const check = true;
  while (check) {
    const { email, password } = yield take(LOGIN_REQUEST);
    
    const token = yield apiCall(Api.login, email, password);

    if (token) {
      sessionStorage.setAuthToken(JSON.stringify(token));
      const parsedAccessToken = parseJwtToken(token.auth_token);
      const role = parsedAccessToken["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"];
      yield put(setLoginSuccess());
	  
      }
    }
  }

Also in the above piece of code, we parse the JWTToken to get the role of the user which is called as claim.

Below is the code parsing the JWT token,

function parseJwt(token) {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
return JSON.parse(window.atob(base64));
}

When our server gets a request to authenticate a user through an authorization token, here’s what happens:

  • The token is decoded and the ID is extracted from the payload.
  • This user ID is checked in the user database.
  • Now the request token and user model token is compared. If there’s a match, the authentication of the user is complete. If not, then the user doesn’t get access.

Logging Out

When the JWT token is created, we should also set some expiry for the same. This way the token becomes invalid after a certain time frame. There is also a mechanism through which the token can be refreshed in order to avoid any misuse of the token.

ReactJS Private Route

In the ReactJS, router is an important component, which helps in synchronizing your URL and UI. In this section, we will understand how we can use private and public routes.

Let’s first see the structure of a simple application:

  • Everyone has access to the home/login/register pages, so it is a public route.
  • Authenticated users have access to the dashboard / my account page, so it is a private route.

Private Route

In the PrivateRoute component, every route of your app is included. When a user has logged in, they can see the components of this route. For instance, the dashboard. If this user is not logged in, then they are redirected or transferred to the sign-in page.

We can define a private route as shown below. As you can see in the code, we get the role which is derived and stored in the session as explained in the above section. Based on the role we give the access to the component or else we redirect to the login screen

export const PrivateCandidateRoute = ({ component: Component, ...rest }) => {
    const { location } = rest;
    const role = helper.fetchRole();
    let isCandidate = false;
    if (role == constant.CANDIDATE_ROLE) {
        isCandidate = true;
    }
    const adminRol = isCandidate == true ? true : false;
    return (
        <Route {...rest} render={(props) =>
            adminRol ?
                <Component {...rest} {...props} /> :
                <Redirect to={{ 
                    pathname: constant.LOGIN_SCREEN,
                    state: {
                        prevLocation: location
                    }
                }} />
        } />
    );
};

Public Route

PublicRoute offers access to restricted as well as public components. A public route may look as below :-

<Route path={constant.SEARCH_SCREEN} render={() => <SearchScreenContainer {...props} />} />

Summary

Once any user has logged into the REST API, the JWT token is created. With the help of this token, the required role is extracted, which helps in offering and showing pages the user is authorized to see. If authorized, this user would be able to see website pages of private routes too.

Desuvit has years of experience and expertise in mobile app development. Contact us to know more.

Enjoyed this article? Subscribe for more valuable and great content !

Enter your email address below to get new articles with valuable content delivered straight to your inbox, plus special subscriber-only content to help you with your next mobile app or software development project.

By subscribing, you agree with our privacy policy and our terms of service.