abernier / uest

https://www.npmjs.com/package/uest
9 stars 1 forks source link

Can I use uest to share state across express apps/middleware? #8

Open KenEucker opened 3 years ago

KenEucker commented 3 years ago

Hello !

I just discovered your package here and wanted to ask you about a potential implementation of it, if you had a moment to help me understand if it is possible given my use case, I would greatly appreciate it.

My use case is this: I have a multitenant setup of Expressjs with multiple sub-apps and middlewares that intercept all traffic across the subdomains of the host. I am also using Passportjs to authenticate users and provide credentials for certain features across my app.

My problem to solve is this: I cannot authenticate with passport and share that state across apps. I've tried a couple of different solutions, but my thinking is that because these are separately created apps (const newApp = express() ; mainApp.use(newApp)) that passport isn't able to span the req object modifications across each app.

The behavior I'm experiencing is this: A user can go to login.{host} and login with any of the passport authentication strategies I am using. Then, the user is logged in and cookies/session state is saved for that user on the domain login.{host}. However, they are not logged in anywhere else on the host; {host}, other.{host}, etc... all appear to have separate states when it comes to the req object and passport's method of authenticating (req.isAuthenicated() === false on all others). I can do other.{host}/login to login to the other.{host} subdomain of the app and req.isAuthenticated becomes true for that domain but the user isn't shared. I am hoping to have a single landing page for logging in across all of the different subdomains, or just some of the subdomains based on roles and permissions.

How I think uest may be able to help: Sharing state? If I put uest in front of my subdomain routing (which I handle entirely within Express, not outside of the application in any way through DNS or proxy) can I inject the authentication from one subdomain to all of the others? I am thinking of something like the example below, but I don't know if I am fully understanding this right.

const uest = require('uest')

app.use(uest())

app.all((req, res, next) => {
return req.uest({
    method: 'POST',
    url: '/api/sessions',
    body: {email, password}
  }, (er, resp, body) => {
    if (er) {
      // Deal with specific "Forbidden" error
      if (er.status === 403) {
        return res.render('login', {error: "Wrong login/password"})
      }

      return next(er); // for any other error
    }

    console.log('User-session created for', body.user)

    // `req.session` is up-to-date
    console.log(`Welcome back ${req.session.user.firstname}!`

    res.redirect('/profile')
  })
}
)

I've been searching for a way to resolve this issue I am having. I have been concerned that what I am trying to do is not possible and that it is a limitation of subdomains and requests in the browser/express. Did I just get lucky and stumble across the solution to all my woes here? Is this package made to be used for exactly the problem I am experiencing? Thank you for your insights on this.

Note: I will try to put uest into my codebase sometime this week and actually do some testing. I just wanted to ask this question ahead of that in case I'm just totally misunderstanding. Thanks for contributing to FOSS! <3