@binajmen
Maybe getInitialProps without middleware is your solution. For me it is. I check the auth status via getInitialProps in _app and pass the result to all other getInitialProps on any page where I can access it. Furthermore I make it available inside my components with a react context provider.
_app.tsx
import { AuthProvider, getUser } from '../src';
...
...
return (
<Provider store={store}>
<AuthProvider myAuth={props.auth}>
<ThemeProvider theme={theme}>
<GlobalStyles />
<Component {...pageProps} />
</ThemeProvider>
</AuthProvider>
</Provider>
);
}
...
...
CustomApp.getInitialProps = async (appContext) => {
const auth = await getUser(appContext.ctx); //Checking auth status via backend req res
appContext.ctx.customProp = auth;
const appProps = await App.getInitialProps(appContext);
return { ...appProps, auth: auth };
};
/src/index.tsx
export const getUser = async (ctx): Promise<{ isAuth: boolean; user: any } | any> => {
const cookies = ctx?.req?.cookies ? ctx.req.cookies : undefined;
const config = {
url: 'http://localhost:8800/authApi',
method: 'post',
withCredentials: true,
data: { cookieFromServer: true, cookies: cookies },
headers: {
'Content-Type': 'application/json',
},
};
return await axios
.request(config)
.then((response) => {
if (response.data) {
return { isAuth: true, user: response.data };
} else {
return { isAuth: false, user: null };
}
})
.catch((error) => {
return { isAuth: false, user: null };
});
};
export const AuthProvider = (props) => {
const auth = props.myAuth || { isAuth: false, user: null };
const login = async (email, password) => {
// Use any auth service methods here
return await axios({
method: 'post',
url: `${process.env.NEXT_PUBLIC_API_URL}/login`,
data: { email, password },
withCredentials: true,
})
.then(() => {
router.push('/');
console.log('user signed in');
})
.catch((error) => {
console.log('Incorrect email or password entered.', error);
});
};
const register = async (email, password) => {
return await axios({
method: 'post',
url: `${process.env.NEXT_PUBLIC_API_URL}/register`,
data: { email, password },
withCredentials: true,
})
.then(function (response) {
router.push('/');
console.log('user registered');
})
.catch(function (error) {
console.error(error.message);
});
};
const logout = async () => {
return await axios
.get(`${process.env.NEXT_PUBLIC_API_URL}/logout`, {
withCredentials: true,
})
.then(() => {
router.push('/');
console.log('user logged out');
})
.catch((error) => {
console.error(error.message);
});
};
return (
<AuthContext.Provider
value={{ auth, logout, register, login }}
{...props}
/>
);
};
export const useAuth = () => useContext(AuthContext);
export const AuthConsumer = AuthContext.Consumer;
After that, you can access it in any page via getInitialProps or
/pages/login
import { useAuth } from '../../../src';
function LoginPage() {
const { auth, login, register } = useAuth();
...
...
LoginPage.getInitialProps = async (appContext) => {
console.log('getInitialProps', appContext.customProp); // >>> Check that your custom props (auth/getUser) have been passed
appContext.res.writeHead(302, {
Location: '/',
'Content-Type': 'text/html; charset=utf-8',
});
appContext.res.end();
};
export default LoginPage;
In case of any question, feel free to ask me....
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4