NextAuth - How to incrementally expand authenticated scope?

Viewed 40

Hello I'm using the google auth provider with firebase/firestore (incidentally, i had to hack the firebase adapter following this )

I want to be able to incrementally expand scope with the GAPI, as this is the best practice for user experience:

Login with google provider and the base scope When the user requests higher-permission services, pop the oauth screen again to expand scope Is there a good way to do this?

thanks

1 Answers

I resolved this by adding two providers and then calling the different providers in sequence

Next-Auth config: /api/auth/[...nextauth.ts]

import GoogleProvider from "next-auth/providers/google"; // from next auth
import GmailProvider from "next-auth-custom/GmailProvider"; // from below

export default NextAuth({
  providers: [
    GoogleProvider(config),
    GmailProvider(config),
  ]
});

GmailProvider at next-auth-custom/GmailProvider

import type { OAuthConfig, OAuthUserConfig } from "next-auth/providers";
import { GoogleProfile } from "next-auth/providers/google";
export interface Google extends Record<string, any> {
  aud: string;
  azp: string;
  email: string;
  email_verified: boolean;
  exp: number;
  family_name: string;
  given_name: string;
  hd: string;
  iat: number;
  iss: string;
  jti: string;
  name: string;
  nbf: number;
  picture: string;
  sub: string;
}

export default function Google<P extends GoogleProfile>(
  options: OAuthUserConfig<P>
): OAuthConfig<P> {
  return {
    id: "gmail",
    name: "Gmail",
    type: "oauth",
    wellKnown: "https://accounts.google.com/.well-known/openid-configuration",
    authorization: {
      params: {
        scope: "openid https://www.googleapis.com/auth/gmail.send",
      },
    },
    idToken: true,
    checks: ["pkce", "state"],
    profile(profile) {
      return {
        id: profile.sub,
        name: profile.name,
        email: profile.email,
        image: profile.picture,
      };
    },
    options,
  };
}

Button which takes the provider as a prop:

const GoogleLoginButton: React.FC<ButtonProps> = ({
  prompt = "Login with Google",
  provider = "google",
}) => {
  return (
    <GoogleButton onClick={() => signIn(provider)}>
      <FaGoogle /> {prompt}
    </GoogleButton>
  );
};

export default GoogleLoginButton;
Related