Setup Project#

GitHub this note shows how to create a new nextjs project

npx create-app-next@latest .

Install amplify and amplify-ui

npm install aws-amplify @aws-amplify/ui-react

Here is the project structure

|--app
|--page.tsx
|--layout.tsx
|--global.css
|--blog
|--page.tsx
|--profile
|--page.tsx
|--src
|--aws-exports.js
|--amplify

Amplify#

Let init a Amplify backend project

amplify init

Add auth and storage

amplify add auth

and

amplify add storage

The src/aws-exports.js look like this

const awsmobile = {
aws_project_region: "ap-southeast-1",
aws_cognito_identity_pool_id:
"ap-southeast-1:333a91e2-9c01-429a-b64b-16b153ebb969",
aws_cognito_region: "ap-southeast-1",
aws_user_pools_id: "ap-southeast-1_YnXNtaD2M",
aws_user_pools_web_client_id: "295oq682rmglodotr6b59e19u6",
oauth: {},
aws_cognito_username_attributes: ["EMAIL"],
aws_cognito_social_providers: [],
aws_cognito_signup_attributes: ["EMAIL"],
aws_cognito_mfa_configuration: "OFF",
aws_cognito_mfa_types: ["SMS"],
aws_cognito_password_protection_settings: {
passwordPolicyMinLength: 8,
passwordPolicyCharacters: [],
},
aws_cognito_verification_mechanisms: ["EMAIL"],
aws_user_files_s3_bucket:
"nextjsamplifyauth228f39f651114b57a2674b641e8be550343-dev",
aws_user_files_s3_bucket_region: "ap-southeast-1",
};
export default awsmobile;

withAuthenticator#

Let create a login page client side as

"use client";
import awsmobile from "./../src/aws-exports";
import { Amplify } from "aws-amplify";
import { withAuthenticator } from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";
try {
Amplify.configure({ ...awsmobile, ssr: true });
} catch (error) {
console.log(error);
}
const Home = () => {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div>Hello</div>
</main>
);
};
export default withAuthenticator(Home);

Sever Side Auth#

Let crate a protected page sever side render as below

  • withSSRContext with retreive token and session from cookies
  • setup withSSRContext both at client and server side
import { headers } from "next/headers";
import { Amplify, withSSRContext } from "aws-amplify";
import awsmobile from "../../src/aws-exports";
Amplify.configure({ ...awsmobile, ssr: true });
const getAuth = async () => {
const req = {
headers: {
cookie: headers().get("cookie"),
},
};
// console.log(req);
const SSR = withSSRContext({ req });
try {
const res = await SSR.Auth.currentAuthenticatedUser();
console.log(res.signInUserSession.idToken);
const user = JSON.stringify(res);
// console.log(user);
return JSON.stringify(user);
} catch (error) {
console.log(error);
return "";
}
};
const Profile = async () => {
const user = await getAuth();
return <div>Hello Hai Tran {user} </div>;
};
export default Profile;

Storage Client#

As the withSSRContext does not support storage at the server side yet, so we have to do it at client. Let create a blog page which get signed url image from S3.

"use client";
import { Amplify, Storage } from "aws-amplify";
import awsmobile from "../../src/aws-exports";
Amplify.configure({ ...awsmobile, ssr: true });
Amplify.configure(awsmobile);
const getAuth = async () => {
let url = null;
try {
url = await Storage.get("dolphin.png");
} catch (error) {
console.log(error);
}
return url;
};
const Profile = async () => {
const url = await getAuth();
return url ? (
<div>
<div className="mx-auto max-w-lg">
<img src={url}></img>
</div>
</div>
) : (
<div>Please login first</div>
);
};
export default Profile;