soofstad / react-oauth2-pkce

Provider agnostic OAuth2 Authorization Code flow with PKCE for React
MIT License
126 stars 52 forks source link

Question: Is there a way in which I can configure multiple OAuth providers at once? #186

Closed praveen-cimmra closed 3 weeks ago

praveen-cimmra commented 2 months ago

Summary

In my application, I want to support Google, Microsoft, LinkedIn OAuth. Is there a way in which I can configure support for all of these 3?

Basic Example

[Btn1 - Sign in using Google] [Btn1 - Sign in using LinkedIn] [Btn1 - Sign in using Microsoft]

Drawbacks

None

Unresolved questions

No response

Implementation PR

No response

Reference Issues

No response

sebastianvitterso commented 2 months ago

Yep! Store three configs in your code, one for each, and set up the application to use the specified one at the button click. Idea:

import { createContext, useContext, useState } from 'react'
import { AuthProvider, type TAuthConfig } from 'react-oauth2-code-pkce'

// OAuthProviderSelectingContext.ts
type Provider = 'google' | 'linkedIn' | 'microsoft'
const OAuthProviderSelectingContext = createContext<{
  setProvider: React.Dispatch<React.SetStateAction<Provider>>
  provider: Provider
  currentConfig: TAuthConfig
}>(undefined)
export const OAuthProviderSelectingProvider = (props: { children: React.ReactNode }) => {
  const googleConfig: TAuthConfig = {/**/}
  const linkedInConfig: TAuthConfig = {/**/}
  const microsoftConfig: TAuthConfig = {/**/}
  const [provider, setProvider] = useState<Provider>(undefined)

  function getConfig() {
    switch (provider) {
      case 'google': return googleConfig
      case 'linkedIn': return linkedInConfig
      case 'microsoft': return microsoftConfig
    }
  }
  const currentConfig = getConfig()
  return (
    <OAuthProviderSelectingContext.Provider value={{ setProvider, provider, currentConfig }}>
      {props.children}
    </OAuthProviderSelectingContext.Provider>
  )
}

// App.tsx

export const App = () => {
  return (
    <OAuthProviderSelectingProvider>
      <InnerApp />
    </OAuthProviderSelectingProvider>
  )
}

const InnerApp = () => {
  const { currentConfig } = useContext(OAuthProviderSelectingContext)
  return (
    <AuthProvider authConfig={currentConfig}>
      <ProviderSelector />
    </AuthProvider>
  )
}

// ProviderSelector.tsx

export const ProviderSelector = () => {
  const { setProvider } = useContext(OAuthProviderSelectingContext)
  return (
    <div>
      <button onClick={() => setProvider('google')}>Google</button>
      <button onClick={() => setProvider('linkedIn')}>LinkedIn</button>
      <button onClick={() => setProvider('microsoft')}>Microsoft</button>
    </div>
  )
}

Something like this should do the trick.

praveen-cimmra commented 2 months ago

Thanks, @sebastianvitterso will check that out!