I am trying to migrate react to react native since I want to make an application next after I made the website, but since some syntaxes of react-native seems to be different than typical react. I am just fairly new to react-native, so I think the problem is with the way react-native handle token. Graphql queries and mutations seems to be working fine but my jwt token and authentication seems to take a hit.
Code
apolloClient.js
import { ApolloClient } from "@apollo/client/core";
import { InMemoryCache } from "@apollo/client/cache";
import { setContext } from "@apollo/client/link/context";
import { createUploadLink } from "apollo-upload-client";
import AsyncStorage from "@react-native-async-storage/async-storage";
const httpLink = createUploadLink({
uri: "http://localhost:5001/graphql",
});
const authLink = setContext(() => {
const token = AsyncStorage.getItem("jwtToken");
return {
headers: {
Authorization: token ? `Bearer ${token}` : "",
},
};
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
});
export default client;
auth.js
import { useReducer, createContext, useEffect } from "react";
import jwtDecode from "jwt-decode";
import AsyncStorage from "@react-native-async-storage/async-storage";
const initialState = {
user: null,
};
if (typeof window !== "undefined") {
if (AsyncStorage.getItem("jwtToken")) {
const decodedToken = jwtDecode(AsyncStorage.getItem("jwtToken"));
if (decodedToken.exp * 1000 >= Date.now()) {
initialState.user = decodedToken;
}
}
}
const AuthContext = createContext({
user: null,
login: (userData) => {},
logout: () => {},
});
function authReducer(state, action) {
switch (action.type) {
case "LOGIN":
return {
...state,
user: action.payload,
};
case "LOGOUT":
return {
...state,
user: null,
};
default:
return state;
}
}
function AuthProvider(props) {
const [state, dispatch] = useReducer(authReducer, initialState);
// const router = useRouter();
function login(userData) {
AsyncStorage.setItem("jwtToken", userData.token);
dispatch({
type: "LOGIN",
payload: userData,
});
}
function logout() {
AsyncStorage.removeItem("jwtToken");
// toast.error("Logged out successfully", shortToastConfig);
dispatch({ type: "LOGOUT" });
}
useEffect(() => {
if (state.user) {
const decodedToken = jwtDecode(AsyncStorage.getItem("jwtToken"));
const timeLeft = decodedToken.exp * 1000 - Date.now();
setTimeout(() => {
dispatch({
type: "LOGOUT",
});
AsyncStorage.removeItem("jwtToken");
// toast.error("Session Expired", shortToastConfig);
// router.push("/login");
}, timeLeft);
}
}, [state]);
return (
<AuthContext.Provider
value=
{...props}
/>
);
}
export { AuthContext, AuthProvider };
App.js
import React from 'react';
import { ApolloProvider } from '@apollo/client';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { useFonts } from 'expo-font';
import {
MyShop,
SignIn,
SignUp,
Navigator,
Chats,
ShoppingCart,
Settings,
// Country,
Me,
Home,
Categories,
SubCategories,
Products,
} from './screens';
import { AuthProvider } from './context/auth';
import client from './context/apolloClient';
export default function App() {
LogBox.ignoreAllLogs(true);
const Stack = createStackNavigator();
return (
<ApolloProvider client={client}>
<AuthProvider>
<NavigationContainer>
<Stack.Navigator
screenOptions=
initialRouteName="Navigator"
>
<Stack.Screen
name="Navigator"
component={Navigator}
options=
/>
<Stack.Screen
name="Home"
component={Home}
options=
/>
{/* <Stack.Screen
name="Country"
component={Country}
options=
/> */}
<Stack.Screen
name="SignIn"
component={SignIn}
options=
/>
<Stack.Screen
name="SignUp"
component={SignUp}
options=
/>
<Stack.Screen
name="Me"
component={Me}
options=
/>
<Stack.Screen name="MyShop" component={MyShop} />
<Stack.Screen name="ShoppingCart" component={ShoppingCart} />
<Stack.Screen name="Chats" component={Chats} />
<Stack.Screen name="Settings" component={Settings} />
{/* Other Pages */}
<Stack.Screen name="Categories" component={Categories} />
<Stack.Screen name="SubCategories" component={SubCategories} />
<Stack.Screen name="Products" component={Products} />
</Stack.Navigator>
</NavigationContainer>
</AuthProvider>
</ApolloProvider>
);
}
Error Shown:
If you need more code I can be transparent and edit this post, and if u don't understand what I mean or trying to point out please comment down below if you can, and if you would be kind enough also to give me some few tips and advice on react-native so I could learn more about it. Thank you!!
from Invalid Token Specified in React Native (JWT Authentication)
No comments:
Post a Comment