DEV Community

Vicky V
Vicky V

Posted on • Updated on

How to create an auth login system with axios interceptors (TypeScript) PART I

Hi guys!

In this article I am sharing a small process of an auth system using axios interceptors. The concept below, is that, when you submit your email or password you want to check if that user exists on the server and if the user is authenticated then the user would be able to navigate to other pages.

More information about interceptors you can check here.

You could simply do a post request inside your SignIn component however if one day lets say axios doesn't exist anymore and you want to be able to change what you used in just one place but not the logic behind it then interceptors is the way to go. Also this is a concept recently came across called [MVP] - minimum viable product - LINK, still trying to get my head around it but is good to know.

By the way the article is giving you an idea how that works of course you would need to add your own bits and pieces, api etc...

So let's take a step back.

What I am sharing below is:

  • Setup the connection with a server.

  • Create a service layer

Set up with a server

  1. Create your client, which is the connection with your API.

Below the REACT_APP_API_URL could be your own API saved on your .env file or .env.local

interface ConfigType {
  ApiUrl: string
}

const config: ConfigType = {
  ApiUrl: process.env.REACT_APP_API_URL || '',
}

export default config
Enter fullscreen mode Exit fullscreen mode

Here we have our http-client file.


import axios from 'axios'
import config from './config'
import setupInterceptorsTo from './http-client-interceptor'

const instance = axios.create({
  baseURL: config.ApiUrl,
  headers: {
    'Content-type': 'application/json',
  },
})

export default setupInterceptorsTo(instance)

Enter fullscreen mode Exit fullscreen mode

Create the service layer

Below we have the interceptors which will handle our error messages because there is always different type of errors.


import { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'
import { toast } from 'react-toastify'
import { isObject, isEmpty } from 'lodash'

const API_DEFAULT_MESSAGE_REQUEST = 'The request is invalid'

function handleError(serverError: any) {
  if (isObject(serverError)) {
    Object.entries(serverError).forEach(([, value]) => {
      const errorMessage = isEmpty(value) ? API_DEFAULT_MESSAGE_REQUEST : value
      toast.error(`${errorMessage}`)
    })
  }
}

const onRequest = (config: AxiosRequestConfig): AxiosRequestConfig => {
  return config
}

const onResponseError = (error: AxiosError): Promise<AxiosError> => {
  handleError(error?.response?.data)
  return Promise.reject(error)
}

export default function setupInterceptorsTo(axiosInstance: AxiosInstance): AxiosInstance {
  axiosInstance.interceptors.request.use(onRequest, undefined)

  axiosInstance.interceptors.response.use(undefined, onResponseError)

  return axiosInstance
}

Enter fullscreen mode Exit fullscreen mode

Here is where we actually send a request to the server in this case a post request.


import { BehaviorSubject } from 'rxjs'
import { isNull } from 'lodash'
import httpClient from '../../shared/http-client'

interface LoginRequestModel {
  email: string
  password: string
}

const currentUserSubject = isNull(localStorage.getItem('current_user'))
  ? new BehaviorSubject(null)
  : new BehaviorSubject(JSON.parse(localStorage.getItem('current_user')!))

export const currentUserValue = currentUserSubject.value

export async function login(requestData: LoginRequestModel): Promise<string> {
  const response = await httpClient.post('/auth/login', requestData)

  const { access_token: accesstoken } = response.data

  return accesstoken
}
Enter fullscreen mode Exit fullscreen mode

Finally you can call your login function on your SignIn component and the only thing you need to do is to use it in an async way where await login(data). Thats the only input it gets since above you have the schema for this function and it does all the work for us isolated.

Discussion (2)

Collapse
sebastien_rodrigues_37 profile image
Sebastien Rodrigues

Hi it miss the httpclient file, and how to add bearer token on interceptor.

Collapse
vikirobles profile image
Vicky V Author

Hi I just added which picture is the http-client file.
As for the bearer token I will update the article once I finish it as well. The current code is not finished fully yet as I mentioned at the beginning of the article thats a part of a logic. But will update once I completed as well on the project. :)