DEV Community

Alfredo Baldoceda
Alfredo Baldoceda

Posted on

Implementing User Authentication in a Blog Application using AWS Amplify, NextJS, and Google Sign-In

In this tutorial, we will walk through the process of implementing user authentication in a blog application using AWS Amplify, NextJS, and Google Sign-In. Adding user authentication to your blog application allows users to authenticate themselves and edit their blogs securely. This feature enhances the user experience and adds an extra layer of security to your application.


Prerequisites

Before getting started, make sure you have the following prerequisites:

If you haven't already done so, we recommend checking out our previous blog post on adding a post data model with Amplify.

Additionally, we suggest following the hosting blog before adding authentication, as it provides instructions that will be helpful in this blog.


Step 1: Set up Google Console OAuth

Before adding social authentication to our app, we need to configure Google OAuth. Follow these steps:

1. Go to the Google Cloud Console and create a new project.

2. Set up the OAuth consent screen by selecting API & Services in the left menu, then Oauth Consent screen. Choose External as the User Type, enter an App Name, and optionally upload a logo.

Google Consent Screen

Google OAuth Consent

Google Consent Summary

3. After completing the consent screen, go to credentials under API & Services and create an OAuth Client ID. Choose Web Application as the application type and enter a name to identify your client. Leave the Authorized JavaScript origins and Authorized redirect URIs blank for now.

Google Console Creds

4. Take note of the Google Web Client ID and Google Client Secret generated for your OAuth flow.


Step 2: Set up AWS Amplify Authentication

Now, let's set up AWS Amplify Authentication and configure Google Sign-In as a social provider. Follow these steps:

1. Ensure you have Amplify set up and a GraphQL API created. You can check the status by running amplify status in your terminal. You can also follow our past tutorial where we initiate and host an amplify project.

    Current Environment: dev

┌──────────┬──────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name        │ Operation │ Provider plugin   │
├──────────┼──────────────────────┼───────────┼───────────────────┤
│ Hosting  │ amplifyhosting       │ Create    │                   │
├──────────┼──────────────────────┼───────────┼───────────────────┤
│ Api      │ albacdev             │ No Change │ awscloudformation │
└──────────┴──────────────────────┴───────────┴───────────────────┘
Enter fullscreen mode Exit fullscreen mode

2. Add a new Amplify Authentication and Google Sign-In as a social provider by running the following command in your terminal:

   $ amplify add auth
Enter fullscreen mode Exit fullscreen mode

Choose Default configuration with Social Provider (Federation) when ask for the default authentication and security configuration. Select Email as the sign-in option and configure advanced settings as needed. Enter your chosen domain name prefix, redirect sign-in and sign-out URIs (e.g., http://localhost:3000), and choose Google as the social provider.


$ amplify add auth
Using service: Cognito, provided by: awscloudformation

  The current configured provider is Amazon Cognito

  Do you want to use the default authentication and security configuration? Default configuration with Social Provider (Federation)
  Warning: you will not be able to edit these selections.
  How do you want users to be able to sign in? Email
  Do you want to configure advanced settings? No, I am done
  What domain prefix do you want to use?
  Enter your redirect signin URI: http://localhost:3000/
 ? Do you want to add another redirect signin URI No
  Enter your redirect signout URI: http://localhost:3000/
 ? Do you want to add another redirect signout URI No
  Select the social providers you want to configure for your user pool: Google

  You've opted to allow users to authenticate via Google. If you haven't already, you will need to go to https://developers.google.com/identity and create an App ID.

  Enter your Google Web Client ID for your OAuth flow: XXXXXXXXXXXXXXX
  Enter your Google Web Client Secret for your OAuth flow: XXXXXXXXXXXXXXXXXXXXXXXXX

Enter fullscreen mode Exit fullscreen mode

3. Provide your Google Web Client ID and Google Client Secret when prompted.

Once the setup is complete, Amplify will add the necessary auth resources locally.

Amplify OAuth Success

Take a note of the Hosted UI Endpoint and go back to Google Console OAuth Credentials, type it into your user pool domain into Authorized Javascript origins and with the /oauth2/idpresponse endpoint into Authorized Redirect URIs.

Step 2: Set Up Groups and Permissions

To control access to our application, we need to set up groups and permissions. This can be done using the AWS CLI or Amplify Studio. Here's an example of how to do it using the CLI:

1. Add groups using the following command:

   amplify auth add-group
Enter fullscreen mode Exit fullscreen mode

2. Add permissions using the following command:

   amplify auth add-permission
Enter fullscreen mode Exit fullscreen mode

You can also set up groups and permissions using Amplify Studio, which provides a visual interface for managing authorization rules.

Studio Admin Queries


Step 3: Modify Your NextJS Code

Now that we have set up the authentication provider, social provider, groups, and permissions, we need to modify our NextJS code to handle the sign-in and sign-out workflow and display a list of blogs that the user can edit.

1. Load the authentication setup by calling Amplify.configure and loading the aws_exports configuration in the _app.js file.

   Amplify.configure({
     ...awsconfig,
     ssr: true,
     DataStore: {
       authModeStrategyType: AuthModeStrategyType.MULTI_AUTH,
     },
   });
Enter fullscreen mode Exit fullscreen mode

This enables server-side rendering (SSR) and the MULTI_AUTH strategy for our data store, allowing us to have permissions for both Cognito groups and social provider groups.

2. Add the Authenticator.Provider to your _app.js file:

   <Authenticator.Provider>
       <Component {...pageProps} />
   </Authenticator.Provider>
Enter fullscreen mode Exit fullscreen mode

This sets up the authentication provider for your application.

3. Use the useAuthenticator hook in your NavBar-Menu component to check if the user is authenticated. Show the SignOut button if the user is authenticated against Cognito or the Google provider; otherwise, show the SignIn button to allow users to authenticate.

const { user } = useAuthenticator((context) => [context.user]);
...
...
 {user ? <SignOutButton username={user.username} /> : <SignInButton />}
...
Enter fullscreen mode Exit fullscreen mode

4. Create the necessary routes and components for the sign-in and sign-out functionality.

On the SignIn button we only use next/link to redirect the request to the /signin page:

<Link className="text-white" href="/signin">
Enter fullscreen mode Exit fullscreen mode

On the SignIn page we are using the Authenticator component, customized with our Logo and use ThemeProvider to enable dark mode:

...
import {
  Authenticator,
  defaultDarkModeOverride,
  ThemeProvider,
  useTheme,
  View,
} from "@aws-amplify/ui-react";
...
...
 const theme = {
    name: "my-theme",
    overrides: [defaultDarkModeOverride],
    tokens: {
      components: {
        textareafield: {
          rows: { value: "{20}" },
          size: { value: "large" },
          resize: { value: "vertical" },
        },
      },
    },
  };

  const components = {
    Header() {
      const { tokens } = useTheme();

      return (
        <div className="mx-32">
        <View textAlign="center" padding={tokens.space.large}>
          <ImageS3 alt="Amplify logo" src="albac_logo" />
        </View>
        </div>
      );
    },
  };
...
...
          <Authenticator components={components}>
            <>{errorMessage && <p>Error: {errorMessage}</p>}</>
            <ThemeProvider theme={theme} colorMode="system" />
          </Authenticator>
...

Enter fullscreen mode Exit fullscreen mode

5. Protect restricted routes from non-authenticated users. Wrap the components that require authentication with the Authenticator component.

On the blog-edit page, we do the same to protect from non-authenticated users.

          <Authenticator components={components}>
            <>{errorMessage && <p>Error: {errorMessage}</p>}</>
            <ThemeProvider theme={theme} colorMode="system">
              <NewPostsUpdateForm
                mode="Dark"
                id={id}
                onSuccess={() => router.push("/blog/" + id)}
                onError={(error) => {
                  setErrorMessage(error);
                }}
              />
            </ThemeProvider>
          </Authenticator>
Enter fullscreen mode Exit fullscreen mode

After this is setup you should be able to see the login page from Amplify ui component and able using cognito.

Amplify Cognito

By following these steps, you should be able to implement user authentication in your NextJS blog application using AWS Amplify, NextJS, and Google Sign-In.


Conclusion

In this tutorial, we have learned how to implement user authentication in a blog application using the powerful combination of AWS Amplify, NextJS, and Google Sign-In. By following the step-by-step guide, you can enhance your blog application and provide a secure environment for users to manage their blogs.

User authentication is an essential feature for web applications, and with AWS Amplify, the process becomes seamless and efficient. By integrating Google Sign-In as a social provider, you allow users to authenticate themselves easily while maintaining a high level of security.

By implementing user authentication, you can ensure that only authorized users can access and edit their blogs, enhancing the overall user experience and adding an extra layer of security to your application. Additionally, with the flexibility and scalability of AWS Amplify, you can easily adapt and expand your authentication system as your application grows.


Reference


Top comments (0)