I am trying to work on a React application where I want to implement role-based authorization.
My goal is to fetch user roles from an API and store them in context so they can be accessed throughout the application. I am using the Context API and React Query for state management and data fetching.
I am having trouble finding information about how to do so effectively as most information about it seems to be using old formats. Or is just about Authentication rather than Authorization.
I saw some people recommeding to use JWT-decoder on React but I dont know how safe it is to decode your token In the Client Side… nor how to properly implement it.
What I was trying to do was fetch the role straight from the server and save the data in a context and then just if check all protected routes for the correct roles (or especialidades for this proyect)
This is the context I was trying to make work:
const AuthContext = createContext<string[] | undefined>(undefined);
export const AuthContextProvider = ({children} :{children:ReactNode})=>{
const {data:roles} = useQuery({
queryFn: ()=> fetchRole(),
queryKey: ["roles"],
})
const userRoles = roles || [];
return(
<AuthContext.Provider value={userRoles}>
{children}
</AuthContext.Provider>
)
}
export const useAuthContext = ()=>{
const context = useContext(AuthContext);
return context;
}
// The fetch function
export const fetchRole = async ():Promise<string[]>=>{
const response = await fetch("http://localhost:3000/api/auth/check-role",{
credentials: "include",
});
if (!response.ok) {
throw new Error("Something went wrong...");
}
return response.json();
}
//The backend Route, MiddleWare and Response
authRoutes.get('/check-role',verifyToken,async ( req:Request, res:Response)=>{
console.log(req.medicoInfo.especialidad)
res.status(200).json({medicoRoles: req.medicoInfo.especialidad});
})
const verifyToken = (req: Request, res: Response, next: NextFunction)=>{
const token = req.cookies["auth_cookie"];
console.log(token);
if(!token){
return res.status(401).json({message: "Unauthorized"});
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET as string);
req.medicoInfo = (decoded as JwtPayload).medicoInfo;
next();
} catch (error) {
return res.status(401).json({message: "Unauthorized"});
}
}
//MiddleWare
const verifyToken = (req: Request, res: Response, next: NextFunction)=>{
const token = req.cookies["auth_cookie"];
console.log(token);
if(!token){
return res.status(401).json({message: "Unauthorized"});
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET as string);
req.medicoInfo = (decoded as JwtPayload).medicoInfo;
next();
} catch (error) {
return res.status(401).json({message: "Unauthorized"});
}
}
The data is being fetched but How can I implement it.. How can I make it so this data protects my Routes, and help the users navigate safely through an app.
Should I change my Context? I saw somewhere that I should just both send the token and the roles when Sign In but I am beyond lost how could I use them. I just don’t know whats the next step after fetching and just putting them in a context or if it even is the best option.