It is time to set up your assignment. Here, we will use the information from the previous two chapters to set-up your applications database and authentication.
You can use code from your tutorial assignment or use the lecture repository below
https://github.com/WesternSydneyUniversity/comp3036-lecture-nextjs
First, we need to install the necessary package; we are going to use the latest version 5 (which is currently in beta).
In the /apps/admin
directory, run the following command:
pnpm add next-auth@beta
Next, we need to generate the secret that next-auth package uses. Run, the following command:
pnpx auth secret
In the next step, we will have to register the generated environment variable to the environment configuration.
In the packages/env
, we need to set up our environmental variables for safe use. The login process will require five secrets:
AUTH_SECRET
.GOOGLE_CLIENT_ID
, GOOGLE_CLIENT_SECRET
.GITHUB_CLIENT_ID
,GITHUB_CLIENT_SECRET
. Adding the specification of these variables in this package will allow the system to check for missing variables upon deployment. Please open the packages/env/admin.ts
file and add the following lines:
export const env = createEnv({
...
server: {
PASSWORD: z.string(),
JWT_SECRET: z.string(),
// These are new
DATABASE_URL: z.string().url(),
AUTH_SECRET: z.string(),
GITHUB_CLIENT_ID: z.string(),
GITHUB_CLIENT_SECRET: z.string(),
GOOGLE_CLIENT_ID: z.string(),
GOOGLE_CLIENT_SECRET: z.string(),
},
...
runtimeEnv: {
PASSWORD: process.env.PASSWORD,
JWT_SECRET: process.env.JWT_SECRET,
// These are new
DATABASE_URL: process.env.DATABASE_URL,
AUTH_SECRET: process.env.AUTH_SECRET
GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID,
GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,
},
...
});
If you try to run your admin project now, you will see the following error in your console:
We need to add current values in the .env file to fix this. Please see the two previous sections to see what values need to be filled out.
.env.local
file and delete that file afterwards)Your .env
file should look similar to the following (replace `xxxxx
` with your values):
PASSWORD=xxxxx
JWT_SECRET=xxxxx
AUTH_SECRET=xxxxx
DATABASE_URL="file:./dev.db"
GITHUB_CLIENT_ID=xxxxx
GITHUB_CLIENT_SECRET=xxxxx
GOOGLE_CLIENT_ID=xxxxx
GOOGLE_CLIENT_SECRET=xxxxx
Try running pnpm dev
and your application should now start!
We need to prepare the user model and create a new task model to handle the application data. Please open schema.prisma
file in your opened project and modify the User model to look as the following:
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? // @db.Text
access_token String? // @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? // @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
userId String
expires DateTime
sessionToken String @unique
accessToken String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
accounts Account[]
sessions Session[]
}
model VerificationRequest {
id String @id @default(cuid())
identifier String
token String @unique
expires DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([identifier, token])
}
Once you are done, you are ready to load these changes to your database. Please run the following command in the terminal in your project folder:
pnpm prisma db push
or
pnpm prisma migrate dev --name add_aurhentication
In the terminal window, you should see the following message: “Your database is now in sync with your schema.”
Could you try opening your database in a database client to see these changes? Database clients are visual tools that allow you to see your data, manipulate it, and administer your whole database server. Concerning database clients, there are many options, let's mention a few:
Whichever option you choose is up to you, but have one database client ready to check out your data at any time! Let's get set up our client to use Prisma!
It is time to tell your application that you will be using “Github” and “Google” as your authentication providers. In the apps/admin
package, please create the src/server/auth.ts file
. We have to add this provider to the list of providers. find the “providers” key in your authOptions
and add the following setup code (or just search for “…add providers here”):
import GoogleProvider from 'next-auth/providers/google';
import GitHubProvider from 'next-auth/providers/github';
import NextAuth from "next-auth"
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
GitHubProvider({
clientId: env.GITHUB_CLIENT_ID,
clientSecret: env.GITHUB_CLIENT_SECRET
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
],
session: {
strategy: 'jwt',
},
})
Next, create the authentication route at /app/api/auth/[...nextauth]/route.ts
:
import { handlers } from "@/server/auth" // Referring to the auth.ts we just created
export const { GET, POST } = handlers
You can also create a middleware to keep the session alive in the file src/middleare.ts
export { auth as middleware } from "@/auth"
And done! You just saved yourself about a month of work and a lot of headaches!
In the apps/admin
create a new sign-in page at src/app/signin/page.tsx
with the following code:
import { signIn } from "@/server/auth"
export default function Page() {
return (
<form
action={async () => {
"use server"
await signIn()
}}
>
<button type="submit">Sign in</button>
</form>
)
}
Now:
pnpm dev
again (if not running alreadyhttp://localhost:3000/signin
Click on “Sign In”