Home > Mobile >  Store bearer token in header
Store bearer token in header

Time:01-12

This is my first time using Context API and I'm confused on how to store the bearer token that I receive from the API in the authorization header. I saw some tutorials on YouTube and tried to apply them on my code but didn't had much success. I'll leave the code of my Context and my login. The login is OK, the API call is OK, is just about storing the bearer token.

Login.jsx

  const handleSubmit = (event) => {
    event.preventDefault();
   // dispatch({type: "LOGIN_START"})
       login({ username, password }, dispatch);
  };

{...}

AuthActions.js

export const loginStart = () => ({
    type: "LOGIN_START",
  });
  export const loginSuccess = (user) => ({
    type: "LOGIN_SUCCESS",
    payload: user,
  });
  export const loginFailure = () => ({
    type: "LOGIN_FAILURE",
  });
  
  //logout
  
  export const logout = () => ({
    type: "LOGOUT",
  });

AuthContext.js

import AuthReducer from "./AuthReducer";
import { createContext, useEffect, useReducer } from "react";

const INITIAL_STATE = {
  user: JSON.parse(localStorage.getItem("user")) || null,
  isFetching: false,
  error: false,
};

export const AuthContext = createContext(INITIAL_STATE);

export const AuthContextProvider = ({ children }) => {
  const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE);

  useEffect(() => {
    localStorage.setItem("user", JSON.stringify(state.user));
  }, [state.user]);

  return (
    <AuthContext.Provider
      value={{
        user: state.user,
        isFetching: state.isFetching,
        error: state.error,
        dispatch,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

AuthReducer.js

const AuthReducer = (state, action) => {
    switch (action.type) {
      case "LOGIN_START":
        return {
          user: null,
          isFetching: true,
          error: false,
        };
      case "LOGIN_SUCCESS":
        return {
          user: action.payload,
          isFetching: false,
          error: false,
        };
      case "LOGIN_FAILURE":
        return {
          user: null,
          isFetching: false,
          error: true,
        };
      case "LOGOUT":
        return {
          user: null,
          isFetching: false,
          error: false,
        };
      default:
        return { ...state };
    }
  };
  
  export default AuthReducer;

The response

{data: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTgwL…MzMX0.rpa4DVG8pERVERks4W9_tknFQUCOvIc3GCZZGbW3HU0', status: 200, statusText: '', headers: {…}, config: {…}, …}
config: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
data: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTgwLCJ1c2VybmFtZSI6InRlc3RlNDUiLCJpYXQiOjE2NDE5NDY3MzEsImV4cCI6MTY0MTk1MDMzMX0.rpa4DVG8pERVERks4W9_tknFQUCOvIc3GCZZGbW3HU0"
headers: {content-length: '170', content-type: 'application/json; charset=utf-8'}
request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status: 200
statusText: ""
[[Prototype]]: Object

CodePudding user response:

In order to access your context value you should use the useContext hook passing it your context. This will return your value and you should then access your user. So after your login request, you should do something like (assuming res is your response body) :

const ctx = useContext(AuthContext);
ctx.dispatch("LOGIN_SUCCESS", res.data);

This will call your reducer and update your shared context state. In subsequent requests, in order to access your API key you just have to do :

const ctx = useContext(AuthContext);

and access the user property from the context. You should as well create a hook to gain direct access to any property you like. The key point here is that with the useContext hook you get the value you passed as your context provider prop.

  •  Tags:  
  • Related