sergiodxa / remix-auth-oauth2

A OAuth2Strategy for Remix Auth
https://sergiodxa.github.io/remix-auth-oauth2/
MIT License
150 stars 56 forks source link

Dynamic callbackURL #80

Closed tadeaspetak closed 3 months ago

tadeaspetak commented 8 months ago

First of all, thanks a lot for your work on this library!

I'm trying to incorporate it into our stack and have just hit a crucial issue: I need the callbackURL to be dynamic. Our code serves multiple domains and only when the user attempts to authenticate do we know what the callbackURL should be. Is this by any chance possible?

With passport, this was achieved by providing an overriding callbackURL during the authenticate call, like:

 app.get('/api/auth/facebook', (req, res, next) =>
    passport.authenticate('facebook', {
      callbackURL: getFacebookCallbackUrl(req)
    })(req, res, next),
  );

Thanks a lot in advance!

sergiodxa commented 8 months ago

You will have to create the strategy on the request and use authenticator.use there to add the strategy.

bluefire2121 commented 3 months ago

@sergiodxa - so in 2.0 the callbackURL and ResponseTypes are gone?

type ResponseType = "id_token" | "token" | "id_token token" | "code" | "code id_token" | "code id_token token";
export interface OAuth2StrategyOptions {
    authorizationURL: string;
    tokenURL: string;
    clientID: string;
    clientSecret: string;
    callbackURL: string;
    scope?: string;
    responseType?: ResponseType;
    useBasicAuthenticationHeader?: boolean;
}

How do we pass the Request to the strategy so that it has knowledge of the domain?

sergiodxa commented 3 months ago

so in 2.0 the callbackURL and ResponseTypes are gone?

The callbackURL was replaced by redirectURI which is the name commonly used by providers.

The ResponseType is not needed anymore, OsloJS takes care of that.


How do we pass the Request to the strategy so that it has knowledge of the domain?

The strategy receives the request already, but it doesn't use it to know the domain, what you need to do is to create the strategy instance on a per request basis, e.g.

import { sessionStorage } from "~/session.server"

type User = /* define your type */

function createAuthenticator(request: Request) {
  let authenticator = new Authenticator<User>(sessionStorage)

  let options: OAuth2StrategyOptions = {
    // define the strategy options here, use `request` to access the domain
  }

  authenticator.use(new OAuth2Strategy(options, verify)

  return authenticator
}
bluefire2121 commented 3 months ago

Thanks @sergiodxa for the hint. I updated my loaders & actions to create the strategy on each request:

  const authenticator = await createAuthenticator(request);
  const user = await authenticator.isAuthenticated(request, {
    failureRedirect: `/login?returnTo=${pathname}`,
  });