I have a react native application. I am making an authenticated API call to my serve using a GET request.
I am confident that this error is on the client side as I can see the request processed and returned on the server-side while I watch the EC2 instance execute the response. Token is valid, endpoint is valid, information is returned.
What I do see is an error
const response = axiosContext.authAxios
.get("/dashboard")
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error); // here undefined is not an object (evaluating 'config.cancelToken')
});
I do not call the cancel request I am aware there is one in Axios; why this is showing I am unsure.
AxiosContext.js
import React, { createContext, useContext } from "react";
import axios from "axios";
import { AuthContext } from "./AuthContext";
import createAuthRefreshInterceptor from "axios-auth-refresh";
import * as Keychain from "react-native-keychain";
import { getSecretValueFor, isSessionTokenExpired } from "../helpers/common";
const AxiosContext = createContext();
const { Provider } = AxiosContext;
const AxiosProvider = ({ children }) => {
const authContext = useContext(AuthContext);
const authAxios = axios.create({
baseURL: "http://someAPiIcom:443",
timeout: 9000,
});
const publicAxios = axios.create({
baseURL: "http://someAPI.com:443",
timeout: 9000,
});
authAxios.interceptors.request.use(
(config) => {
if (!config.headers.Authorization) {
return getSecretValueFor("session_token")
.then((session_token) => {
config.headers.Authorization = session_token; // gets the jwt I store ( works and accepted by server
return config
})
.catch((error) => {
console.log(error);
});
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
const refreshAuthLogic = (failedRequest) => {
const data = {
refreshToken: authContext.authState.refreshToken,
};
const options = {
method: "POST",
data,
url: "http://localhost:3000/api/refreshToken",
};
return axios(options)
.then(async (tokenRefreshResponse) => {
failedRequest.response.config.headers.Authorization =
"Bearer " + tokenRefreshResponse.data.accessToken;
authContext.setAuthState({
...authContext.authState,
accessToken: tokenRefreshResponse.data.accessToken,
});
await Keychain.setGenericPassword(
"token",
JSON.stringify({
accessToken: tokenRefreshResponse.data.accessToken,
refreshToken: authContext.authState.refreshToken,
})
);
return Promise.resolve();
})
.catch((e) => {
authContext.setAuthState({
accessToken: null,
refreshToken: null,
});
});
};
createAuthRefreshInterceptor(authAxios, refreshAuthLogic, {});
return (
<Provider
value={{
authAxios,
publicAxios,
}}
>
{children}
</Provider>
);
};
export { AxiosContext, AxiosProvider };
AuthContext.js
import React, { createContext, useState } from "react";
import * as Keychain from "react-native-keychain";
import {
saveSecretValue,
getUTCTimestamp,
getSecretValueFor,
} from "../helpers/common";
const AuthContext = createContext(null);
const { Provider } = AuthContext;
const AuthProvider = ({ children }) => {
const [authState, setAuthState] = useState({
accessToken: null,
refreshToken: null,
authenticated: null,
});
const logout = async () => {
await Keychain.resetGenericPassword();
setAuthState({
accessToken: null,
refreshToken: null,
authenticated: false,
});
};
const getAccessToken = () => {
getSecretValueFor("session_token")
.then((session_token) => {
return session_token;
})
.catch((error) => {
return error;
});
};
return (
<Provider
value={{
authState,
getAccessToken,
setAuthState,
logout,
}}
>
{children}
</Provider>
);
};
export { AuthContext, AuthProvider };
Main.js
import { AuthContext } from "./context/AuthContext";
import { AxiosContext } from "./context/AxiosContext";
const Stack = createStackNavigator();
export default function Main(props) {
const [status, setStatus] = useState("loading");
const authContext = useContext(AuthContext);
const axiosContext = useContext(AxiosContext);
const loadJWT = useCallback(async () => {
try {
const response = axiosContext.authAxios
.get("/dashboard")
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error); // error thrown here
});
console.log(response);
const jwt = await getSecretValueFor("session_token");
authContext.setAuthState({
accessToken: jwt.accessToken || null,
refreshToken: jwt.refreshToken || null,
authenticated: jwt.accessToken !== null,
});
const isTokenExpired = isSessionTokenExpired(jwt);
if (isTokenExpired) {
console.log("Token expired");
await setStatus("error");
} else {
console.log("Token valid");
await setStatus("success");
}
} catch (error) {
console.log(error);
await setStatus("error");
// useEffect(() => { setStatus("success") })
console.log(`Keychain Error: ${error.message}`);
authContext.setAuthState({
accessToken: null,
refreshToken: null,
authenticated: false,
});
}
}, []);