I’m just trying out auth0 and nextjs, so apologies if this is a silly question, but what I’d like to do is if a user is not signed in when trying to access certain pages, I’d like them to be redirected to the index page.
The default behavior is to redirect users to the sign in page on auth0.
import React from 'react';
import { withPageAuthRequired } from '@auth0/nextjs-auth0';
export default function Profile({ user }) {
return (
user && (
<div>
<img src={user.picture} alt={user.name} />
<h2>{user.name}</h2>
<p>{user.email}</p>
<a href="/api/auth/logout">Logout</a>
</div>
)
);
}
export const getServerSideProps = withPageAuthRequired();
Is there a way to configure this behavior or is it only possible in client side rendering?
import {getServerSidePropsWrapper, getSession} from '@auth0/nextjs-auth0';
export const getServerSideProps = getServerSidePropsWrapper(async (ctx) => {
const session = getSession(ctx.req, ctx.res);
if (session) {
// Use is authenticated
} else {
// User is not authenticated
return {
redirect: {
destination: '/', // or any other page you want to redirect unauthorised users
permanent: false,
},
}
}
});
But I’m not sure whether security is uncompromised with this workaround, though.
By browsing the source code, I get an impression that both withPageAuthRequired() and getSession() appear to use the same piece of code to obtain a session (sessionCache.get()).
On the other hand, the API reference states that you would write the code like this if
you’re using >=Next 12 and getSession or getAccessToken without withPageAuthRequired , because you don’t want to require authentication on your route…
which sounds like we shouldn’t use the above code for protected pages.
I need some help from someone who knows well about what goes on behind withPageAuthRequired().
My solution: rewrite withPageAuthRequiredFactory to allow customizing redirect destination.
export function withPageAuthRequiredFactory(redirectDestination: string): WithPageAuthRequired {
return ({ getServerSideProps, returnTo } = {}) =>
async (ctx) => {
// original `assertCtx` is changed to the following
if (!ctx.req) {
throw new Error('Request is not available');
}
if (!ctx.res) {
throw new Error('Response is not available');
}
// original `getSessionCache` is changed to the following
const session = await getSession(ctx.req, ctx.res);
if (!session?.user) {
return {
redirect: {
destination: redirectDestination,
permanent: true,
}
};
}
let ret: any = { props: {} };
if (getServerSideProps) {
ret = await getServerSideProps(ctx);
}
if (ret.props instanceof Promise) {
return { ...ret, props: ret.props.then((props: any) => ({ user: session.user, ...props })) };
}
return { ...ret, props: { user: session.user, ...ret.props } };
};
}