loopback-next icon indicating copy to clipboard operation
loopback-next copied to clipboard

How to integrate passport authentication without express web app?

Open apfz opened this issue 2 years ago • 0 comments

Describe the bug

I have my front-end separated from my loopback application and I am trying to implement authentication through passport.

However I receive the following error (after it is making a GET request to https://myapi.com/auth/thirdparty/twitter):

Request GET /auth/thirdparty/twitter failed with status code 500. InternalServerError: Error: OAuth authentication requires session support. Did you forget to use express-session middleware?

The only adjustment I have made is to remove the web-application folder from the loopback-passport example repository.

I then tried to integrate it with my React JS application.I made slight modifications to the src/controllers/oauth2.controller.ts:

@authenticate('oauth2')
  @get('/auth/thirdparty/{provider}')
  /**
   * This method uses the @authenticate decorator to plugin passport strategies independently
   *
   * Endpoint: '/auth/thirdparty/{provider}'
   *          an endpoint for api clients to login via a third party app, redirects to third party app
   */
  loginToThirdParty(
    @param.path.string('provider') provider: string,
    @inject(AuthenticationBindings.AUTHENTICATION_REDIRECT_URL)
    redirectUrl: string,
    @inject(AuthenticationBindings.AUTHENTICATION_REDIRECT_STATUS)
    status: number,
    @inject(RestBindings.Http.RESPONSE)
    response: Response,
  ) {
    return {redirectUrl: redirectUrl};
  }

  @oAuth2InterceptExpressMiddleware()
  @get('/auth/thirdparty/{provider}/callback')
  /**
   * This method uses the passport strategies as express middleware
   *
   * Endpoint: '/auth/thirdparty/{provider}/callback'
   *          an endpoint which serves as a oauth2 callback for the thirdparty app
   *          this endpoint sets the user profile in the session
   */
  async thirdPartyCallBack(
    @param.path.string('provider') provider: string,
    @inject(SecurityBindings.USER) user: UserProfile,
    @inject(RestBindings.Http.REQUEST) request: Request,
    @inject(RestBindings.Http.RESPONSE) response: Response,
  ) {
    // const profile = {
    //   ...user.profile,
    // };
    // request.session.user = profile;
    // response.redirect('/auth/account');
    return response;
  }

In src/authentication-strategy-providers/twitter.express-mv.ts I also tried to set session to false:

@injectable.provider({scope: BindingScope.SINGLETON})
export class TwitterOauthExpressMiddleware implements Provider<ExpressRequestHandler> {
  constructor(
    @inject('twitterStrategy')
    public twitterStrategy: TwitterStrategy,
  ) {
    passport.use(this.twitterStrategy);
  }

  value() {
    return passport.authenticate('twitter',{session: false});
  }
}

but unfortunately no luck.

Any support is welcome!

Logs

No response

Additional information

No response

Reproduction

apfz avatar Oct 24 '23 19:10 apfz