Anto Subash.

Table of contents

Intro

In this post we will see how to create a Identity server Client and configure it to implement authenticate for the Next.js Application.

1. Adding a new client to the IdentityServer

first step is to create a new client for the nextjs application. list of client is available in the appsettings.json file at DbMigrator project.

1.1 Add the new json entry

1"Todos_Spa_1": {
2    "ClientId": "Todos_Spa_1",
3    "ClientSecret": "1q2w3e*",
4    "RootUrl": "http://localhost:3000"
5},

1.2 Update the CreateClientsAsync method

In the Domain project there is a IdentityServerDataSeedContributor class which has the CreateClientsAsync method. This method creates the Identity server clients during the migrations. so we will update this method to include the new json entry.

1// React Client
2var reactClient = configurationSection["Todos_Spa_1:ClientId"];
3if (!reactClient.IsNullOrWhiteSpace())
4{
5    var webClientRootUrl = configurationSection["Todos_Spa_1:RootUrl"]?.TrimEnd('/');
6
7    await CreateClientAsync(
8        name: reactClient,
9        scopes: commonScopes,
10        grantTypes: new[] { "client_credentials", "authorization_code" },
11        secret: (configurationSection["Todos_Spa_1:ClientSecret"] ?? "1q2w3e*").Sha256(),
12        requireClientSecret: false,
13        redirectUri: $"{webClientRootUrl}/authentication/login-callback/identity-server4",
14        postLogoutRedirectUri: $"{webClientRootUrl}",
15        corsOrigins: new[] { webClientRootUrl.RemovePostFix("/") }
16    );
17}

1.3 Run the migration

Now run the migration to add the client to the DB.

2. Create Next.js App

1yarn create next-app

3. Add next-auth package

1yarn add next-auth

4. Add .env file

1NEXTAUTH_URL=http://localhost:3000
2NEXT_PUBLIC_API_URL=https://localhost:44391
3IdentityServer4_Domain=localhost:44354
4IdentityServer4_CLIENT_ID=Todos_Spa_1
5IdentityServer4_CLIENT_SECRET="1q2w3e*"
6NODE_TLS_REJECT_UNAUTHORIZED=0

NEXT_PUBLIC_API_URL is the ABP application url.

NEXTAUTH_URL is the nextjs app url.

NODE_TLS_REJECT_UNAUTHORIZED is set to 0 to work with ssl in localhost.

5. Setup next-auth

create a /pages/api/auth/[...nextauth].js and add the following

1import NextAuth from "next-auth";
2import Providers from "next-auth/providers";
3
4export default NextAuth({
5  // Configure one or more authentication providers
6  providers: [
7    Providers.IdentityServer4({
8      id: "identity-server4",
9      name: "IdentityServer4",
10      scope: "openid profile email Todos offline_access", // Allowed Scopes
11      domain: process.env.IdentityServer4_Domain,
12      clientId: process.env.IdentityServer4_CLIENT_ID,
13      clientSecret: process.env.IdentityServer4_CLIENT_SECRET,
14    }),
15  ],
16  callbacks: {
17    /**
18     * @param  {object} session      Session object
19     * @param  {object} token        User object    (if using database sessions)
20     *                               JSON Web Token (if not using database sessions)
21     * @return {object}              Session that will be returned to the client
22     */
23    async session(session, token) {
24      // Add property to session, like an access_token from a provider.
25      session.accessToken = token.accessToken;
26      return session;
27    },
28
29    async jwt(token, user, account, profile, isNewUser) {
30      // Add access_token to the token right after signin
31      if (account?.accessToken) {
32        token.accessToken = account.accessToken;
33      }
34      return token;
35    },
36  },
37});

6. Create login Component

1import React from "react";
2import { signIn, signOut, useSession } from "next-auth/client";
3function Login() {
4  const [session, loading] = useSession();
5
6  return (
7    <>
8      {!session && (
9        <>
10          Not signed in <br />
11          <button onClick={() => signIn("identity-server4")}>Sign in</button>
12        </>
13      )}
14      {session && (
15        <>
16          Signed in as {session.user.email} <br />
17          <button onClick={() => signOut()}>Sign out</button>
18        </>
19      )}
20    </>
21  );
22}
23
24export default Login;

7. Render the login component

Now you can render the login component in any page to trigger the auth.

<Login></Login>

Buy Me a Coffee at ko-fi.com