Inside our src folder, we will have an api folder and inside it we have an auth.js file, here is where we put our authentication functions.
- Create a function
registerthat takesuserInfoas a parameter and send a post request to the register end-point with theuserInfo. (This step is already done) - Go to
Register.jspage and importregisterfunction fromapi/auth.js. - Use the
useMutationhook with theregisterfunction and pass ituserInfo - Call your mutate function inside the
handleFormSubmitfunction! - Now go to
auth.jsin the api folder and add the following code to yourregisterfunction:
const formData = new FormData();
for (const key in userInfo) formData.append(key, userInfo[key]);- Then, replace the
userInfoinside the post request withformData. - This step will enable you to send files with the request
- Create a function
loginthat takesuserInfoas a parameter and send a post request to the login end-point with theuserInfo. (This step is already done) - Go to
Login.jspage and import theloginfunction fromapi/auth.js. - Use the
useMutationhook with theloginfunction and pass ituserInfo. - Call your mutate function inside the
handleFormSubmitfunction!
- In auth.js create the storeToken function
const storeToken = (token) => {
localStorage.setItem("token", token);
};- Now go to both
loginandregisterfunctions and callstoreToken()after getting the data and pass it your data.token
const login = async (userInfo) => {
try {
const { data } = await instance.post("/auth/login", userInfo);
storeToken(data.token); // <--- This
return data;
} catch (error) {
console.log(error);
}
};
const register = async (userInfo) => {
try {
// This is for seding the request with files
const formData = new FormData();
for (const key in userInfo) formData.append(key, userInfo[key]);
// END
const { data } = await instance.post("/auth/register", formData);
storeToken(data.token); // <--- This
return data;
} catch (error) {
console.log(error);
}
};npm install jwt-decode- In
auth.js, import jwt_decode fromjwt-decodeand create a functioncheckToken. - Inside it create a variable
tokenthat retrieves the token from yourlocalStorageusing getItem. - Now check if token is available, create a variable
decodethat decodes the token and create a variablecurrentTimethat gives you the current time.(Hint: use Date.now() ) - Now check if the token is expired (Hint: compare the currentTime with decode.exp), if it is expired, remove the token from
localStorageusing removeItem and return false, Otherwise return true. - Also return false outside the if condition.
const checkToken = () => {
const token = localStorage.getItem("token");
if (token) {
const decode = jwt_decode(token);
const cureentTime = Date.now() / 1000;
if (decode.exp < cureentTime) {
localStorage.removeItem("token");
return false;
}
return true;
}
return false;
};- In your src folder, create a
contextfolder, and inside it add aUserContextfile. - Now import
createContextand initialize a UserContext. (Export it)
//src/context/UserContext.js
import { createContext } from "react";
const UserContext = createContext();
export default UserContext;- Now go to
App.jsand importUserContext. - Create a user state and give it false as an initial value.
- Now wrap the whole app with
<UserContext.Provider>and pass it a value of [user, setUser]. - Your App should look like this
function App() {
const [user, setUser] = useState(false);
useEffect(() => {
setUser(checkToken());
}, []);
return (
<UserContext.Provider value={[user, setUser]}>
// ....
// ....
</UserContext.Provider>- Now go to
NavBar.jsinside your components folder, and importuseContext(from react) andUserContextthat we just created - Use useContext hook for
[user and setUser]and give it the (UserContext). Hint:
const [user, setUser] = useContext(UserContext);- Then check if the user is true, show the logout button, if false show the register and login buttons. (hint: search ternary operator).
{
user ? <> /*components*/ </> : <> /*components*/ </>;
}- Go to
auth.jsin the api folder - Create a function
logoutthat removes the token from the localStorage using removeItem.
const logout = () => {
localStorage.removeItem("token");
};- Now go to
NavBar.jsinside your components folder - create a function
handleLogoutthat calls thelogoutfunction fromapi/auth.js - use
setUserfrom the useContext to set the user tofalse - Finally, Pass the
handleLogoutfunction to the onClick method of the logout button.
- In
index.jsinside the api folder, use yourinstanceto create an interceptor using theinterceptors.request.use()and pass it an anonymous function. - If the token is in the localStorage then config.headers.authorization = token.
- return config.
hint:
instance.interceptors.request.use((config) => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});