How to implement authentication in NextJS using Amazon Cognito

5 min readDec 26, 2022


Are you looking to implement authentication forms in your NextJS project using Amazon Cognito? Then this article is for you.

1. Introduction

1.1 Amazon Cognito

Amazon Cognito is an authentication and authorization service that lets you manage your applications’ access control, whether a web or mobile app. Whether dealing with a small number of users or millions, Cognito already has the infrastructure set up for you. It also supports integration with popular identity providers such as Facebook, Google, and Apple. See their documentation.

Amazon Cognito provides a good amount of documentation for any level of developers to start with. They have complete user authentication forms, UI components that you can easily integrate into your application, and a set of APIs you can call in case you want to implement your own custom UI. All these are available from their website at

More than that, it can control access to Amazon resources such as Lambda, databases, and more. But that is a topic for another article.

1.2 NextJS

NextJS is just another open-source front-end web development framework for React. Its selling point is that it can render server-side and generate static websites, which is very good for SEO. What I love about NextJS is their easy-to-read documentation at and examples officially available from their GitHub repository at In a way, NextJS is like Angular Framework for React.

1.3 SSR Support for AWS Amplify

With SSR support, we can now access and verify a token from the request object using Amplify’s library

2. Amazon Cognito Pool

If you haven’t done so, register an account at AWS

2.1 In the Service filter, enter Cognito. Click Manage User Pools.

2.2 Click Create a user pool.

2.3 Enter a Pool name. Click Step through settings.

2.4 Select how you want your users to sign in. For this exercise, we will only allow the email address.

2.5 At the bottom of this screen, you can select which standard attributes you want to include in your users’ profiles. We will use given_name and family_name. Note that we already have access to the email as a username. Click Next Step.

2.6 On the next page, Configure the password strength. Click Next Step.

2.7 For the following settings, leave everything to default and click Next Step.

  • MFA and verifications
  • Messages customizations
  • Tags
  • Devices

2.8 Under App clients, click Add an app client. Let’s name the client Web Client.

  • Uncheck Generate client secret.
  • Check Enable username and password authentication.

Click Create Client.

3. Google Console Identity Provider

If you haven’t done so, create a Google console account at

3.1 Create a new project. Click the arrow down button in the top left corner and New Project.

3.2 Enter your project name.

Wait until the project is successfully created.

Before you continue, ensure the newly created project is selected in the screen’s dropdown located at the top left corner.

*You can default create 25 projects under your Google console account.

3.3 Click the Navigation Menu / API & Services / Credentials.

3.4 Click Create Credentials / OAuth client ID.

3.5 Under Application type, select Web application.

3.6 Enter the name.

3.7 Enter the Authorized Javascript origins and Authorized redirect URIs.

You must get your Cognito domain name and replace the value accordingly: https://<cognitoDomainUrl>/oauth2/idresponse.

And hit save.

3.8 Once it saves, you must get and keep the Client ID and Secret on the right side of this page.

3.9 Once again, click the Navigation Menu / API & Services / and click the OAuth consent screen. This is where you will publish the app when it’s ready for production. You should also add the email addresses of the users you will use for testing. Remember this as it’s essential.

4. The NextJS App

The NextJS project is available at, and the resources that we should look at are:

  • useSession
  • SessionContext
  • WithLayout
  • WithSession
  • Secured
  • secured

Part of the hook that authenticates a user:

const useSession = () => {
const [stage, setStage] = useState(0)
const [isLoading, setLoading] = useState(false)
const [user, setUser] = useState(null) // cognito user
const [isAuthenticated, setIsAuthenticated] = useState(!!user)
const [error, setError] = useState(false)

const refreshState = useCallback(() => {


.then(user => {
.catch(err => {
logger.error("Error authenticating user", err)
if (err === 'not authenticated') {

} else {

return () => {
}, [])
// ...




Open for Collaboration | Senior Java Backend Developer