Hello,
I am building a react app and I’m using a template that is ready and configured to auth0.
There is a hook (useAuth) and a Context that uses auth0-spa-js. (the code below)
This template has a built-in login, signup, and all auth pages.
I really want to use them.
I searched the whole web about auth0 and I saw that I have to redirect or popup the user out of my web app.
Eventually, I need the login page to show immediately on app startup. so I tried to change in the context the login function from “loginWithPopup” to “loginWithRedirect” and call it on the component with useEffect while the user is not authenticated.
It failed with a infinite loop with random redirects to “/?code={RANDOM_CODE}” no matter what ive tried.
Here’s Auth0Context.js code:
import { createContext, useEffect, useReducer } from 'react';
import PropTypes from 'prop-types';
import { Auth0Client } from '@auth0/auth0-spa-js';
// routes
import { PATH_AUTH } from '../routes/paths';
//
import { AUTH0_API } from '../config';
// ----------------------------------------------------------------------
let auth0Client = null;
const initialState = {
isAuthenticated: false,
isInitialized: false,
user: null,
};
const handlers = {
INITIALIZE: (state, action) => {
const { isAuthenticated, user } = action.payload;
return { ...state, isAuthenticated, isInitialized: true, user };
},
LOGIN: (state, action) => {
const { user } = action.payload;
return { ...state, isAuthenticated: true, user };
},
LOGOUT: (state) => ({
...state,
isAuthenticated: false,
user: null,
}),
};
const reducer = (state, action) => (handlers[action.type] ? handlers[action.type](state, action) : state);
const AuthContext = createContext({
...initialState,
method: 'auth0',
login: () => Promise.resolve(),
logout: () => Promise.resolve(),
});
// ----------------------------------------------------------------------
AuthProvider.propTypes = {
children: PropTypes.node,
};
function AuthProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
const initialize = async () => {
try {
auth0Client = new Auth0Client({
domain: AUTH0_API.domain,
client_id: AUTH0_API.clientId,
redirect_uri: window.location.origin,
audience: AUTH0_API.audience,
cacheLocation: 'localstorage',
useRefreshTokens: true
});
await auth0Client.checkSession();
const isAuthenticated = await auth0Client.isAuthenticated();
if (isAuthenticated) {
const user = await auth0Client.getUser();
dispatch({
type: 'INITIALIZE',
payload: { isAuthenticated, user },
});
} else {
dispatch({
type: 'INITIALIZE',
payload: { isAuthenticated, user: null },
});
}
} catch (err) {
console.error(err);
dispatch({
type: 'INITIALIZE',
payload: { isAuthenticated: false, user: null },
});
}
};
initialize();
}, []);
const login = async () => {
await auth0Client.loginWithPopup()
const isAuthenticated = await auth0Client.isAuthenticated();
if (isAuthenticated) {
const user = await auth0Client.getUser();
dispatch({ type: 'LOGIN', payload: { user } });
}
};
const logout = () => {
auth0Client.logout();
window.location.href = PATH_AUTH.login;
dispatch({ type: 'LOGOUT' });
};
return (
<AuthContext.Provider
value={{
...state,
method: 'auth0',
user: {
id: state?.user?.sub,
photoURL: state?.user?.picture,
email: state?.user?.email,
displayName: state?.user?.name,
role: state?.user?.permissions,
},
login,
logout,
}}
>
{children}
</AuthContext.Provider>
);
}
export { AuthContext, AuthProvider };
So,
- I want the login/sign page will be first thing on startup (without button)
- I want to use my own react components pages for that (if possible)
Please help me figure out what is the best way to accomplish my tasks
Thank you so much for anyone who will comment and help.