How to use bearer and oauth2 passport.js strategies togheter?
Asked Answered
H

1

6

Recently I started using passport.js with the oauth2 strategies for authentication. at first, I was using sessions and everything was great but I want my API to be stateless. the only thing I found that could help me with this is the bearer strategy(passport-http-bearer). I can't find any good example of using these two strategies together so I'm a little lost. maybe I'm in the wrong way. Let me explain what I'm trying to do.

Let's say I've configured the google strategy(passport-google-oauth2) like this:

  passport.use(
    new GoogleStrategy(
      {
        clientID: <googleClientId>,
        clientSecret: <googleClientSecret>,
        callbackURL: `localhost:4000/auth/google/callback`,
        scope: ["profile", "email"],
      },
      async function (_accessToken, _refreshToken, profile, done) { // this is the verify function
        let user = <create new user>
        return done(null, user);
      }
    )
  );

this route redirects the user to the google where they will authenticate:

app.get("/auth/google", passport.authenticate("google", { session: false }));

and this one processes the response and logs the user in:

app.get(
  "/google/callback",
  passport.authenticate("google", {
    session: false,
  })
);

The Google strategy issues a bearer token and I want to return that token to the user so I can store it in the client's localStorage and send it in the Authorization header of each request to authenticate the user. My first question is how and where? I have access to the token in the strategy's verify token but I don't know how should I return it to the user in the response body.

I protect the routes that need an authenticated user using the bearer strategy (passport-http-bearer). I've configured it like this:

passport.use(
  new BearerStrategy(async function (token, done) { // this is the verify function
    const user = await userManager.find({ oauthToken: token });
    return done(null, user);
  }) 
);

The first parameter of the verify function is the token that is in the Authorization header. When a user signs up using google, I save the issued token in the database (let's say it is '1234'). users should send their token in the Authorization header (like 'Beader 1234') and if the token is in the database they are authenticated.

now I can protect a route using the bearer strategy:

app.get(
  "/protected",
  passport.authenticate("bearer", { session: false }),
  (req: Request, res: Response) => {
    res.send({ data: req.user });
  }
);

Is saving the google OAuth token in the database ok? do I need to refresh it? What do you think about the whole process that I'm trying to do? I'm coming from the jwt world and it's wired for me.

Hammerskjold answered 19/12, 2021 at 19:16 Comment(0)
H
2

Well, I did more research and now I understand OAuth2 slightly better. Apparently, this is not possible. The access token is generated in the backend and for security reasons should remain in the backend. I can access it in the frontend but the are trade-offs so I got back to the classic session-based solution. Watching the following talk helped me a lot: https://www.youtube.com/watch?v=996OiexHze0

Hammerskjold answered 20/12, 2021 at 17:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.