15

Is it possible to do a social login in Pop-up in next-auth? Or only possible redirecting to provider auth page?

I'm asking because I don't want to lose all application state after redirect to a provider page.

I don't want to save things in database or browser storage.


export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    Providers.Facebook({
      clientId: process.env.FACEBOOK_ID,
      clientSecret: PROCESS.ENV.FACEBOOK_SECRET
    }),
    Providers.Google({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
      authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth?prompt=consent&access_type=offline&response_type=code',
    }),
    Providers.Credentials({
      name: "credentials",
      async authorize(credentials, req) {
        const user = { email: req.body.email }
        return user
      },
    }),
    // ...add more providers here
  ],
  jwt: {
    signingKey: process.env.SIGNINING_KEY,
  },
  callbacks: {
    async signIn(user, account) {
      const { name, email } = user;
      const { provider } = account
  
      try {
        
        
        // Do something

        return true;
      } catch (err) {
        console.log(err)
        return false;
      }
    },

    async jwt(token, user, account) {
      if (account?.accessToken) {
        // some code
      } 
      return token
    },

    async session (session, token) {
      
      session.accessToken = token.accessToken
      return session
    }
  }
})
Brian Burns
  • 20,575
  • 8
  • 83
  • 77
Pedro Carvalho
  • 181
  • 1
  • 4

2 Answers2

5

taken from https://github.com/arye321/nextauth-google-popup-login

add google-signin.js to /pages

google-signin.js:

import { signIn, useSession } from "next-auth/react";
import { useEffect } from "react";

const SignInPage = () => {
    const { data: session, status } = useSession();

    useEffect(() => {
        if (!(status === "loading") && !session) void signIn("google");
        if (session) window.close();
    }, [session, status]);

    return (
        <div
            style={{
                width: "100vw",
                height: "100vh",
                position: "absolute",
                left: 0,
                top: 0,
                background: "white",
            }}
        ></div>
    );
};

export default SignInPage;

in index.js:

import { useSession, signIn, signOut } from "next-auth/react";

export default function Home() {
  const { data: session, status } = useSession();

  const popupCenter = (url, title) => {
    const dualScreenLeft = window.screenLeft ?? window.screenX;
    const dualScreenTop = window.screenTop ?? window.screenY;
    const width =
      window.innerWidth ?? document.documentElement.clientWidth ?? screen.width;

    const height =
      window.innerHeight ??
      document.documentElement.clientHeight ??
      screen.height;

    const systemZoom = width / window.screen.availWidth;

    const left = (width - 500) / 2 / systemZoom + dualScreenLeft;
    const top = (height - 550) / 2 / systemZoom + dualScreenTop;

    const newWindow = window.open(
      url,
      title,
      `width=${500 / systemZoom},height=${550 / systemZoom
      },top=${top},left=${left}`
    );

    newWindow?.focus();
  };

  if (status === "authenticated") {
    return (
      <div>
        < h2 > Welcome {session.user.email} </h2 >
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    )
  }
  else if (status === "unauthenticated") {
    return (
      <div>
        <h2>Please Login</h2>
        <button onClick={() => popupCenter("/google-signin", "Sample Sign In")} >
          Sign In with Google
        </button>
      </div>
    )
  }

  return (
    <div>
      <h1>Loading...</h1>
    </div>
  )
}

credits to https://github.com/krushilnaik/with-prisma-mongodb-nextauth

Arye P.
  • 163
  • 4
  • 11
1

You can call the signIn method from anywhere (Your own Modal component for example) with :

import { signIn } from 'next-auth/react';
...
signIn("credentials", {redirect: false, email, password })
  .then(() => {
     setLoading(false)
     closeModal()
  })

and declare your providers in [...nextauth].ts :

export default NextAuth({
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        username: { label: "Username", type: "text", placeholder: "jsmith" },
        password: {  label: "Password", type: "password" }
      },
      async authorize(credentials, req) {
        const user = { id: 1, name: "J Smith", email: "jsmith@example.com" }
        return user
      }
    })
  ],
  secret: "secret token",
});