Understanding Member Login in Sitecore Before Headless
Before Sitecore adapting to a headless approach, login functionality was integrated through ASP .NET Framework which
relied heavily on server-side controls and configurations. Sitecore.Context
played a central role in
managing user sessions along with setting up roles. Security administrator would restrict the
extranet/Anonymous
role to the member content items and allow domain specific roles to access it.
Generally following would need to happen in order to implement member functionality.
- Sitecore Pages (login, registration, password recovery - no restrictions)
- Roles
- Code (checks user’s input and finds them in core database or adds them for future use)
This mean everything was tightly coupled to Sitecore’s backend infrastructure, from login forms to session handling. Also, it would create users within Sitecore databases which creates extra overload to Sitecore.
Now, things have changed and the transition to headless means moving towards an API-based authentication providing a more decoupled and flexible system. This is where we can take advantage of NextAuth, an open source authentication library designed for NextJS. We recently worked with a client to streamline their authentication flow where we used NextAuth with Sitecore and so in this blog, we’ll go over how to install NextAuth and configure it at a basic level. This is a multiple part series so register to our snack newsletter to receive latest updates from us.
Note: We’ve used NextAuth 4 in this blog and page route for our NextJS application.
What is NextAuth? How Can We Use It with Sitecore?
NextAuth allows you to add authentication to your web application. It has various identity providers, including OAuth, email, and custom login mechanisms which provides flexible and secure way to implement authentication. It also simplifies session management by offering built-in support for JWT token based authentication and database sessions (uses database to store session data).
All authentication checks would happen in the headless solution. Below is a pseudo flow which will integrate Sitecore
with NextAuth (Sitecore Content needs a login field - a checkbox
)
- User requests a page
- NextJS backend makes a layout request
- Checks whether its a login required page
- If yes, check if it they have an active session
- If session found, let them pass through
- If no session, redirect them to login page
- If no, let user pass through
- If yes, check if it they have an active session
Install NextAuth
To install NextAuth, run the following inside your headless site folder (usually its src/rendering
).
npm install next-auth
Add nextauth.ts Route
In order to do a basic configuration of our NextAuth installation we would define the following in our
[…nextauth].ts
. This file will be placed under pages/api/auth
folder which will
capture all routes for any NextAuth related calls.
Configuration Element | Description and Usage |
---|---|
Providers | Services that are used to sign in a user. The example uses Email Provider but you can use Google,
GitHub and many more. Full list - https://next-auth.js.org/providers/ |
Callbacks | Callbacks are functions that are called each time when a certain action happens and you can control what you do with it. Full list - https://next-auth.js.org/configuration/callbacks |
Secret | As the name suggest, it is an env variable that is used to encrypt the generated token. Full list
of env variables - https://next-auth.js.org/configuration/options |
Pages | Pages are nothing but telling NextAuth where your login or logout pages are. By default, NextAuth creates sample pages but if you wish to customize it, then simple modify the value of it. |
// pages/api/auth/[...nextauth].ts
import axios from 'axios';
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
export default NextAuth({
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
email: { label: "Email", type: "text" },
password: { label: "Password", type: "password" },
},
authorize: async (credentials) => {
try {
const res = await axios.get(
"https://jsonplaceholder.typicode.com/users?email=" +
credentials?.email
);
const users = res.data;
const user = users[0];
if (user) {
return { id: user.id, email: user.email, name: user.name };
} else {
return null;
}
} catch (error) {
console.error(error);
return null;
}
},
}),
],
callbacks: {
//called whenever a token is generated or updated
async jwt({ token, user }) {
if (user) {
token.user = user;
}
return token;
},
//called whenever a session is checked
async session({ session, token }) {
session.user = token.user as any;
return session;
},
},
//secret to encrypt the token
secret: process.env.NEXTAUTH_SECRET,
//default pages that comes with NextAuth
pages: {
signIn: "/auth/signin",
signOut: "/auth/signout",
error: "/auth/error",
},
});
Modify next.config.js for Rewrites
To avoid any unexpected route handling or errors, we will explicitly tell NextJS what to do when it receive an api request for NextAuth related calls.
//next.config.js
...
const nextConfig = {
...
async rewrites() {
// When in connected mode we want to proxy Sitecore paths off to Sitecore
return [
// API endpoints
{
source: '/sitecore/api/:path*',
destination: `${jssConfig.sitecoreApiHost}/sitecore/api/:path*`,
},
// media items
{
source: '/-/:path*',
destination: `${jssConfig.sitecoreApiHost}/-/:path*`,
},
// healthz check
{
source: '/healthz',
destination: '/api/healthz',
},
// rewrite for Sitecore service pages
{
source: '/sitecore/service/:path*',
destination: `${jssConfig.sitecoreApiHost}/sitecore/service/:path*`,
},
//rewrite for NextAuth API calls
{
source: '/api/:path*',
destination: '/api/:path*',
},
];
},
...
};
module.exports = () => {
// Run the base config through any configured plugins
return Object.values(plugins).reduce((acc, plugin) => plugin(acc), nextConfig);
};
Wrapping Up: Transitioning Sitecore Authentication to Headless with NextAuth
That’s folks! We briefly looked at how authentication was handled in a non-headless Sitecore solution and the way it’ll be implemented in a headless solution. We also looked at installing NextAuth and do a basic configuration of it. In our next blog, we’ll go over on how to set up a login page and connect it with NextAuth.