Skip to content

Instantly share code, notes, and snippets.

@thevisioner
Created March 7, 2023 18:42
Show Gist options
  • Select an option

  • Save thevisioner/91ea39fd1de1a99ea729fea8f7edabab to your computer and use it in GitHub Desktop.

Select an option

Save thevisioner/91ea39fd1de1a99ea729fea8f7edabab to your computer and use it in GitHub Desktop.

Revisions

  1. thevisioner created this gist Mar 7, 2023.
    6 changes: 6 additions & 0 deletions .env.local.example
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    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
    52 changes: 52 additions & 0 deletions [...nextauth].ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    // 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;
    15 changes: 15 additions & 0 deletions _app.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    // 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>
    );
    }
    26 changes: 26 additions & 0 deletions index.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    // 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>
    </>
    );
    }
    15 changes: 15 additions & 0 deletions next-auth.d.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    // 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"];
    }
    }