Git Product home page Git Product logo

Comments (11)

adamjmcgrath avatar adamjmcgrath commented on May 18, 2024

Hey @Cyben

For protecting your microservice REST apis, you should use JWT authentication (see our quickstart on protecting an APIs https://auth0.com/docs/quickstart/backend/nodejs/01-authorization)

As you pointed out, this SDK is for protecting UI pages of a web application with a session.

So your UI Web App (either a SPA (see auth0-spa-js) or a webapp (this SDK)) logs in and get's an Access Token for a REST API (one of your microservices) that is protected with Access Token (a JWT) authorization

from express-openid-connect.

Cyben avatar Cyben commented on May 18, 2024

Ohhh, thanks.
So what is your recommendation and what is the right way to develop for example a frontend with react or any other framework and backend with node js for rest api for example by using the Authorization code flow

from express-openid-connect.

davidpatrick avatar davidpatrick commented on May 18, 2024

Hey @Cyben if you are using React you can utilize our auth0-react SDK and follow the example on creating a useApi hook https://github.com/auth0/auth0-react/blob/master/EXAMPLES.md#4-create-a-useapi-hook-for-accessing-protected-apis-with-an-access-token

For protecting API routes we have a quickstart that you can follow https://auth0.com/docs/quickstart/backend/nodejs that uses the node-jwks-rsa library. We are working on some documentation for using this library in conjunction https://github.com/auth0/express-oauth2-bearer which will be a more modern library for handling protecting API routes on an Express app.

from express-openid-connect.

Cyben avatar Cyben commented on May 18, 2024

Looking forward for the documentation,
About your answer I took a quick look at the auth0-react SDK, and I guess this is a 'public client' right?
My problem is that I have to work with a 'confidential client' and with the 'Authorization code flow' in the way that the redirect (for getting the code) is made from the frontend of course but then the code to token exchange is made from the backend so the client secret won't be shown in the browser.

If there is a forum for questions like that I would love to here.
And thank you for all your help

from express-openid-connect.

davidpatrick avatar davidpatrick commented on May 18, 2024

Hey @Cyben I apologize, yes the react is for public client. If you are working with the confidential client then you this is the correct library, in conjunction with https://auth0.com/docs/quickstart/backend/nodejs.

For the api endpoints you will want to protect those using https://github.com/auth0/node-jwks-rsa

Here is an example, of how that "might" look

const { auth, requiresAuth } = require('express-openid-connect');
const express = require('express');
const app = express();
const jwt = require('express-jwt');
const jwtAuthz = require('express-jwt-authz');
const jwksRsa = require('jwks-rsa');

const checkJwt = jwt({
  secret: jwksRsa.expressJwtSecret({ jwksUri: `${env.ISSUER_BASE_URL}/.well-known/jwks.json` }),
  audience: 'YOUR_API_IDENTIFIER',
  issuer: env.ISSUER_BASE_URL,
  algorithms: ['RS256']
});

app.use( auth({ authRequired: false }));

// Anyone can access this route
app.get('/', (req, res) => res.send('<a href="/admin">Admin Section</a>'));

// requiresAuth checks authentication.
app.get('/admin', requiresAuth(), (req, res) =>
  res.send(`Hello ${req.oidc.user.sub}, this is the admin section.`)
);

// this is the api section
app.get('/api/private', checkJwt, (req, res) =>
  res.json({
    message: 'Hello from a private endpoint! You need to be authenticated to see this.'
  })
);

from express-openid-connect.

Cyben avatar Cyben commented on May 18, 2024

Hey, thank you very much for your help.
Actually what you sent me is not what I was searching for, but it gave me an idea how to implement what I wanted.

I wanted a confidential client as a frontent and backend.
The same client for both microservices.
I wanted to use the Authorization code flow so the the authorization request (to get the 'code') will be from the frontend and then in the backend there will be the exchange for the token and some protected api's.

My backend code looks like this:

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();

app.use(cors());
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies

const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa');
const { Issuer } = require('openid-client');

let client;

Issuer.discover(env.ISSUER_BASE_URL) // => Promise
  .then(function (Issuer) {
    console.log('Discovered issuer %s %O', Issuer.issuer, Issuer.metadata);
    client = new Issuer.Client({
        client_id: env.CLIENT_ID,
        client_secret: env.CLIENT_SECRET
        redirect_uris: ['http://frontend/oauth-callback'], //frontend callback route
        response_types: ['code'],
      }); // => Client
  });

const checkJwt = jwt({
  secret: jwksRsa.expressJwtSecret({ jwksUri: `${env.ISSUER_BASE_URL}/protocol/openid-connect/certs` }),
  audience: 'AUD',
  issuer: env.ISSUER_BASE_URL,
  algorithms: ['RS256']
});

// I call this route from the frontend to get the authorizaionUrl and then making a redirect from the frontend
app.get('/login', (req, res) => {
    let authUrl = client.authorizationUrl({
        scope: 'openid'
    })
    res.send(authUrl)
})

// I call this route from the frontend to exchange the 'code' with the tokenSet
app.post('/code-to-token-exchange', (req, res) => {
    client.callback('http://frontend/oauth-callback', {code: req.body.code})
    .then((tokenSet) =>{
        console.log(tokenSet)
        console.log(tokenSet.claims())    
        res.send(tokenSet["access_token"])
    })
})

// API SECTION

// Anyone can access this route
app.get('/public', (req, res) => 
  res.json({
    message: 'Hello from a public endpoint! No need to be authenticated to see this.'
  })
);

// This is private and just by adding the access token to the request header it works, otherwise returns 401
app.get('/api/private', checkJwt, (req, res) =>
  res.json({
    message: 'Hello from a private endpoint! You need to be authenticated to see this.'
  })
);

I would love to hear from you what do you think about doing something like that?
And it will be my pleasure to hear some tips and fixes I should make or add.

from express-openid-connect.

Cyben avatar Cyben commented on May 18, 2024

Maybe is there a way of using this lib but instead of making the redirect automatically (when using the Authorization code flow) it will return the authorizationUrl?

from express-openid-connect.

adamjmcgrath avatar adamjmcgrath commented on May 18, 2024

Hey @Cyben - if it's all the same app, you could just use this library and protect /api/private with the session cookie, eg

const { auth, requiresAuth } = require('express-openid-connect');

app.use(
  auth({
    authRequired: false,
  })
);

// Anyone can access this route
app.get('/public', (req, res) => 
  res.json({
    message: 'Hello from a public endpoint! No need to be authenticated to see this.'
  })
);

// This is private, you can only access it with a valid session cookie
app.get('/api/private', requiresAuth(), (req, res) =>
  res.json({
    message: 'Hello from a private endpoint! You need to be authenticated to see this.'
  })
);

from express-openid-connect.

Cyben avatar Cyben commented on May 18, 2024

I have an app, a frontend in react and a backend in node js.
I run them independently.
But they are both the same confidential client (same client id).
I'm using the Authorization code flow, that means that the initial request should be from the frontend to be able to redirect and the exchange of the code to the token should be from the backend because there is a use of the client secret. (This is the best practice)

from express-openid-connect.

adamjmcgrath avatar adamjmcgrath commented on May 18, 2024

I'm using the Authorization code flow, that means that the initial request should be from the frontend to be able to redirect and the exchange of the code to the token should be from the backend because there is a use of the client secret. (This is the best practice)

Sure, if you're happy with this that's fine. You can do the whole Auth code flow (with code exchange) on the front end public client (see https://auth0.com/docs/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce), then you don't need the login and /code-to-token-exchange- since you have an unprotected route doing the code exchange and you're sending the AT to the frontend, I don't see the difference wrt best practice.

Either way, I think this is moved beyond the scope of this library, I recommend you continue the conversation in the Auth0 Community forum to get feedback on general app architectures

from express-openid-connect.

Cyben avatar Cyben commented on May 18, 2024

Thank you very much.

from express-openid-connect.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.