Quickly implement senseless refresh token
Tags: login, javascript, react, vue
Published: 2024-01-19 05:43:38

Some time ago, Alova users frequently received feedback on how to implement a senseless token refresh function like Axios. This is indeed troublesome, and I believe everyone has a deep understanding of it.

It really depresses me to have to repeat it every time. So out of anger, I decided to write a universal token authentication module so that alova users would no longer have to worry about this matter.

Using alova's Token authentication interceptor can perfectly solve the following problems for you:

1. Unify and maintain all codes for token identity authentication, including login, logout, token attachment, token refresh, etc.;
2. Supports verification of token expiration on the client and server, and refreshes the token without any warning;
3. Requests that rely on tokens automatically wait for the token refresh to complete before requesting;
4. Automatically release visitor requests that do not rely on tokens;

The only thing you have to do is configure the role type of the request interface, and then the rest will be automatically taken care of for you.

> Some people may not know it. To give a brief introduction, alova is a request strategy library. Its usage is similar to axios, but you can implement complex requests such as request sharing, paging request, form submission, and breakpoint resume by simply configuring parameters. Etc., there is no need to write a lot of code, improve development efficiency, application performance, and reduce server pressure.

The Token identity authentication module is one of alova's request modules. It is completed through a global interceptor and provides client- and server-based identity authentication respectively.

- Client-based identity authentication: means judging whether the token has expired from the client, such as the token expiration time obtained during login;
- Server-based identity authentication: It indicates whether the token has expired based on the status returned from the server. For example, when `status` is 401, it means it has expired;

Next, let’s talk about server-based identity authentication as an example.

## Install the dependencies first

```bash
#vue
npm install alova @alova/scene-vue --save
# react
npm install alova @alova/scene-react --save
#svelte
npm install alova @alova/scene-svelte --save
```

## Implement nonsensical refresh Token on the server side

When the status returned by the server is that the token has expired (for example, 401), it means that the token needs to be refreshed. At this time, requests initiated during the refresh process will also be waiting.

```javascript
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication({
   refreshTokenOnSuccess: {
     // Triggered when responding, the response and method can be obtained, and a boolean is returned to indicate whether the token has expired.
     // When the server returns 401, it means the token has expired.
     isExpired: response => {
       return response.status === 401;
     },

     // Triggered when the token expires, trigger the refresh token in this function
     handler: async (response, method) => {
       const { token, refresh_token } = await refreshToken();
       localStorage.setItem('token', token);
       localStorage.setItem('refresh_token', refresh_token);
     }
   }
});
```

It will return two interceptor functions, which we can bind to alova's global request interceptor and response interceptor respectively.

```javascript
import { createServerTokenAuthentication } from '@alova/scene-*';
import { createAlova } from 'alova';

const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication({
   // ...
});

const alovaInstance = createAlova({
   // ...
   beforeRequest: onAuthRequired(method => {
     // ...interceptor before original request
   }),
   responded: onResponseRefreshToken((response, method) => {
     //...original response success interceptor
     return response.json();
   })
});
```

Finally, in order to prevent the `refreshToken` request from being intercepted, it is necessary to identify `authRole` as `refreshToken` through metadata.

> For more information about metadata, please go to [method metadata](https://alova.js.org/tutorial/getting-started/method-metadata).

```javascript
export const refreshToken = () => {
   const method = alovaInstance.Get('/refresh_token');
   method.meta = {
     authRole: 'refreshToken'
   };
   return method;
};
```

**In this way, a complete token silent refresh function is completed**

## Release visitor request

Some interfaces do not need to rely on token authentication. We call them "guest requests". At this time, we can set their metadata to `authRole: null` to bypass the front-end interception and allow them to send requests and receive responses smoothly.

```javascript
export const requestTokenNotRequired = () => {
   const method = alovaInstance.Get('/token_not_required');
   method.meta = {
     authRole: null
   };
   return method;
};
```

## End

In addition, the token authentication request module also provides functions based on client status verification (that is, the front end determines whether the token has expired), login interception, logout interception, etc., making the login authentication function simpler. [Documentation of token authentication module is here](https://alova.js.org/tutorial/strategy/tokenAuthentication).

If you have any questions, you can join the following group chat for consultation, or you can publish Discussions in [github repository](https://github.com/alovajs/alova/discussions). If you encounter problems, please also post in [github issues ](https://github.com/alovajs/alova/issues) and we will solve it as soon as possible.

- [Join the Discord community to participate in communication](https://discord.gg/S47QGJgkVb)

You are also welcome to contribute, please go to [Contribution Guide](https://alova.js.org/contributing/overview).