reactjsfetchswaggertokenbearer-token

How to add jwt token to all requests headers for swagger generated fetch typescript client?


I have an app in Spring boot which has swagger and I generated a typescript fetch client from this https://editor-next.swagger.io/. I was wondering how to use jwt with that, more interested I am in how to make after login that all the requests header will have the bearer token.

I tried this solution :

The login endpoint:

authController().loginUsingPOST(account,'')
      .then((res: any)=>{
       // const ceva = res.clone().json()
       if(res.token !== undefined && res.token !== null ){
           dispatch( setToken(res.token.toString()));
          //setToken(res.token.toString());
          history.push({
            pathname: '/',
          })
        }
      })

And also found on internet this solution :

private configuration = () => {
    const openapiConfig = new Configuration();
    openapiConfig.baseOptions = {
      headers: { Authorization: 'Bearer ' + this.accessToken() },
    };
    return openapiConfig;
  };

but unfortunately my generated configuration.ts looks like this : no baseOptions:

export interface ConfigurationParameters {
    apiKey?: string | ((name: string) => string);
    username?: string;
    password?: string;
    accessToken?: string | ((name: string, scopes?: string[]) => string);
    basePath?: string;
}

export class Configuration {
    /**
     * parameter for apiKey security
     * @param name security name
     * @memberof Configuration
     */
    apiKey?: string | ((name: string) => string);
    /**
     * parameter for basic security
     * 
     * @type {string}
     * @memberof Configuration
     */
    username?: string;
    /**
     * parameter for basic security
     * 
     * @type {string}
     * @memberof Configuration
     */
    password?: string;
    /**
     * parameter for oauth2 security
     * @param name security name
     * @param scopes oauth2 scope
     * @memberof Configuration
     */
    accessToken?: string | ((name: string, scopes?: string[]) => string);
    /**
     * override base path
     * 
     * @type {string}
     * @memberof Configuration
     */
    basePath?: string;

    constructor(param: ConfigurationParameters = {}) {
        this.apiKey = param.apiKey;
        this.username = param.username;
        this.password = param.password;
        this.accessToken = param.accessToken;
        this.basePath = param.basePath;
    }
}

I tried like this but it still does not work because requests does not contain header token and I get forbidden.

This is what I tried with accessToken:

export const setToken = createAsyncThunk(
    'user/setToken',
    async (token: string | undefined, { dispatch }) => {
      localStorage.setItem(KEY_TOKEN, token ?? '');
      [setDefaultConfig].forEach((x) => {
        x((conf) => ({
          accessToken:  token === undefined ? undefined : `Bearer ${token}`,
        }));
      });


      return token;
    },
  );

Solution

  • After some painful debugging, I managed to make it to work:

    const customFetch: WindowOrWorkerGlobalScope['fetch'] = async (input: RequestInfo, init?: RequestInit) => {
      // Add your custom headers here
      const customHeaders = {
        'Authorization': {GET AND INSERT TOKEN HERE}
      };
    
      if (init && init.headers) {
        init.headers = new Headers(init.headers);
        Object.entries(customHeaders).forEach(([key, value]) => {
          (init.headers as Headers).append(key, value);
        });
      } else {
        init = { ...init, headers: customHeaders };
      }
    
      return fetch(input, init);
    };
    

    Later when you define configuration, you need to specify it as fetchApi:

    const configuration = new Configuration({
          basePath: 'https://yourendpoi.nt',
          fetchApi: customFetch
        });