Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to integrate Auth0 to Loopback 4?

I'm working in a project with Loopback version 4, a Node.js framework. I need to implement authentication with Auth0. However, it seems Auth0 is not compatible with version 4 of Loopback. I couldn't find any documentation, or even a tutorial, about this subject. Anybody there has ever implement authentication with Auth0 in Loopback 4?

like image 850
blackjack Avatar asked Dec 31 '22 21:12

blackjack


1 Answers

Hello from the LoopBack team 👋

Authentication and authorization are features that we are actively working on right now (as of June 2019). As far as I can tell from Auth0 docs (see Server Client + API: Node.js Implementation for the API), they are using JWT tokens.

Fortunately, we already have an example application demonstrating JWT-based authentication - see https://github.com/strongloop/loopback4-example-shopping

Take a look at JWTService class, it's the place where the client-provided tokens are parsed and verified.

The Express example provided by Auth0 uses express-jwt package that wraps jsonwebtoken into an Express middleware.

In LoopBack, we call jsonwebtoken directly.

To adapt the Express based example provided by Auth0, it should be enough to figure out how to pass relevant bits of express-jwt configuration to jsonwebtoken library.

Here is the configuration copied from Auth0 docs:

// Create middleware for checking the JWT
const checkJwt = jwt({
  // Dynamically provide a signing key based on the kid in the header and the singing keys provided by the JWKS endpoint.
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://YOUR_DOMAIN/.well-known/jwks.json`
  }),

  // Validate the audience and the issuer.
  audience: process.env.AUTH0_AUDIENCE,
  issuer: `https://YOUR_DOMAIN/`,
  algorithms: ['RS256']
});

Here is how LoopBack's JWTService calls jsonwebtoken library:

https://github.com/strongloop/loopback4-example-shopping/blob/5f36ae289f50d67bcdc33637c0323daa1f10e02b/packages/shopping/src/services/jwt-service.ts#L35

const decryptedToken = await verifyAsync(token, this.jwtSecret);

Note that jwtSecret is injected into the service, we are configuring it here:

https://github.com/strongloop/loopback4-example-shopping/blob/2d8978d0d72150caf95573c362402491a92757e7/packages/shopping/src/application.ts#L76-L78

    this.bind(TokenServiceBindings.TOKEN_SECRET).to(
      TokenServiceConstants.TOKEN_SECRET_VALUE,
    );

I believe you need to replace TokenServiceConstants.TOKEN_SECRET_VALUE with the value returned by jwksRsa.

this.bind(TokenServiceBindings.TOKEN_SECRET).to(
  jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://YOUR_DOMAIN/.well-known/jwks.json`
  }),
})

Remaining things to figure out:

  • How to apply audience, issuer and algorithms options.

  • I am not sure if jsonwebtoken supports dynamic secrets out of the box. If the proposal above does not work, then you may need to look into express-jwt sources to find out how they are handling dynamic secrets.

I hope my answer provides enough pointers that will allow you to figure the missing details yourself. It would be great if you could post the full working solution if you manage to work it out.

like image 199
Miroslav Bajtoš Avatar answered Jan 05 '23 15:01

Miroslav Bajtoš