Created
March 7, 2023 18:42
-
-
Save thevisioner/91ea39fd1de1a99ea729fea8f7edabab to your computer and use it in GitHub Desktop.
User Authentication in Next.js with Auth.js and Strapi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| GOOGLE_OAUTH_CLIENT_ID= | |
| GOOGLE_OAUTH_CLIENT_SECRET= | |
| NEXTAUTH_SECRET= | |
| # Use 127.0.0.1 instead of localhost to avoid issues with NextAuth.js | |
| NEXTAUTH_URL=http://127.0.0.1:3000 | |
| STRAPI_BACKEND_URL=http://127.0.0.1:1337 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // pages/api/auth/[...nextauth].ts | |
| import { NextApiRequest, NextApiResponse } from "next"; | |
| import NextAuth, { NextAuthOptions } from "next-auth"; | |
| import GoogleProvider from "next-auth/providers/google"; | |
| export const authOptions: NextAuthOptions = { | |
| providers: [ | |
| GoogleProvider({ | |
| clientId: process.env.GOOGLE_OAUTH_CLIENT_ID!, | |
| clientSecret: process.env.GOOGLE_OAUTH_CLIENT_SECRET!, | |
| }), | |
| ], | |
| callbacks: { | |
| // This method is not invoked when you persist sessions in a database. | |
| async jwt({ token, account }) { | |
| if (account) { | |
| const res = await fetch( | |
| `${process.env.STRAPI_BACKEND_URL}/api/auth/${account.provider}/callback?access_token=${account.access_token}` | |
| ); | |
| const data = await res.json(); | |
| const { jwt, user } = data; | |
| token.accessToken = jwt; | |
| token.userId = user.id; | |
| } | |
| return token; | |
| }, | |
| async session({ session, token, user }) { | |
| // Send properties to the client, like an access_token from a provider. | |
| session.user.accessToken = token.accessToken as string; | |
| session.user.userId = token.userId as number; | |
| return session; | |
| }, | |
| }, | |
| session: { | |
| // The default is `"jwt"`, an encrypted JWT (JWE) stored in the session cookie. | |
| // If you use an `adapter` however, we default it to `"database"` instead. | |
| // You can still force a JWT session by explicitly defining `"jwt"`. | |
| strategy: "jwt", | |
| }, | |
| // Not providing any secret or NEXTAUTH_SECRET will throw an error in production. | |
| secret: process.env.NEXTAUTH_SECRET, | |
| }; | |
| const auth = (req: NextApiRequest, res: NextApiResponse) => | |
| NextAuth(req, res, authOptions); | |
| export default auth; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // pages/_app.tsx | |
| import type { AppProps } from "next/app"; | |
| import { SessionProvider } from "next-auth/react"; | |
| export default function App({ | |
| Component, | |
| pageProps: { session, ...pageProps }, | |
| }: AppProps) { | |
| return ( | |
| <SessionProvider session={session}> | |
| <Component {...pageProps} /> | |
| </SessionProvider> | |
| ); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // pages/index.tsx | |
| import { useSession, signIn, signOut } from "next-auth/react"; | |
| export default function IndexPage() { | |
| const { data: session, status } = useSession(); | |
| const isLoading = status === "loading"; | |
| if (isLoading) return "Loading..."; | |
| if (session) { | |
| return ( | |
| <> | |
| Signed in as {session.user.email} <br /> | |
| <button onClick={() => signOut()}>Sign out</button> | |
| </> | |
| ); | |
| } | |
| return ( | |
| <> | |
| Not signed in <br /> | |
| <button onClick={() => signIn()}>Sign in</button> | |
| </> | |
| ); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // types/next-auth.d.ts | |
| import NextAuth, { DefaultSession } from "next-auth"; | |
| declare module "next-auth" { | |
| /** | |
| * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context | |
| */ | |
| interface Session { | |
| user: { | |
| accessToken: string; | |
| userId: number; | |
| } & DefaultSession["user"]; | |
| } | |
| } |
Author
This saved me so much time, thank you!
Great! 👍
Legend! I am glad that I decided to read comments first in Strapi official documentation. Took 15 minutes to set up :)
Please update.
it's 2026 thanks a bunch for this man, it helped me alot
In case you see this comment I have a Q
Storing the Jwt in the session callback will make it exposed to the client side and Iv seen many people suggest not to do that
what could be a safe way to store it in case we wanna retrieve the jwt and attach it to future requests as an authorization ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This saved me so much time, thank you!