1

I am using Passport-Google-OAuth2.0 and Express-session to authenticate. Use connect-redis to store session,

// app.ts

const RedisStore = connectRedis(session)
export const app = express()
app.set('trust proxy', 1)

export const cookieOptions = {
  maxAge: +COOKIE_MAX_AGE,
  httpOnly: true,
  secure: isProduction,
  signed: true,
}

app.use(
  session({
    store: new RedisStore({ client: redis }),
    secret: env.SESSION_SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: env.cookieOptions,
  })
)
app.use(passport.initialize())
app.use(passport.session())

Log in works, but it cannot log out. This is my attempt:

// Works
router.get('/auth/google', passport.authenticate('google', { scope: ['profile'] }))

// Works
router.get(
  '/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/signin' }),
  async function (_req, res, _next) {
    res.redirect('/')
  }
)

// Not working
router.get('/auth/signout', function (req, res) {
  req.session.destroy(function (err) {
    if (err) console.log(` >> sess.des:`, err)

    req.logout()
    res.clearCookie('connect.sid')
    // res.clearCookie('connect.sid', cookieOptions) // This throws 500 error

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

When I go to http://localhost:8000/auth/signout, it redirects to /outed. I expected it to revoke my authentication state and have to login again.

So, I go to http://localhost:8000/auth/google to log in again, but it keeps redirecting me back to authenticated successful route /.

How do I log out properly with Passport and Redis session?

connect-redis: https://github.com/tj/connect-redis
express-session: https://github.com/expressjs/session
passport-google-oauth2: https://github.com/jaredhanson/passport-google-oauth2

Swix
  • 1,883
  • 7
  • 33
  • 50
  • Passport exposes a [`req.logout()` function](http://www.passportjs.org/docs/logout/) for logging out. Have you tried that? – jfriend00 Jan 25 '21 at 16:43
  • Yes, I tried adding `req.logout()` right above `res.clearCookies()` does not work. – Swix Jan 25 '21 at 16:49
  • First off, you get rid of the `req.session.destory()` and the `res.clearCookie()`. You use only `req.logout()`. See the passport documentation link in my previous comment. And, what does "does not work" mean? What exactly do you observe when you hit your signout route? – jfriend00 Jan 25 '21 at 16:54
  • Hi, I have updated the question. I started with `req.logout()` but it did not work, so I googled and found this: https://stackoverflow.com/a/23724692/10583765 That's why now I'm testing with `req.session.destroy()` and `res.clearCookie()`. When I hit signout route, it redirects me to the `/outed` but it does not actually log me out, it still keeps my google authenticated state. I want to log (A account) out and log (B account) in. – Swix Jan 25 '21 at 17:03
  • What does "it does not actually log me out" mean? What exactly do you observe when you go to your `/auth/google` route? When you say you aren't logged out after hitting the signout route, are you able to go to some other non-login page and still have your whole logged in session? I think you may have to actually log that browser out of Google in order to login with a different Google user. – jfriend00 Jan 25 '21 at 17:08
  • After you've linked your passport to a specific Google login, as long as that browser stays logged in with that Google account, that's the account passport is connected to. At least that's my experience as a user. When I "relogin" to a site using passport and I've linked my login to Google (such as I do with stackoverflow), as long as my Google account is still logged in on that browser, I don't have to do anything. I hit the login link and it just logs me in. It establishes a new local session and hooks up to the Google login that already exists. – jfriend00 Jan 25 '21 at 17:11
  • So, I think you have to log your browser out of Google (outside of passport and outside of your app) if you want to have your app login to a different Google account. – jfriend00 Jan 25 '21 at 17:13
  • I see. I tested on Chromium, so it's possible. Please allow me to try with non-Google auth, such as Facebook or Twitter. brb. – Swix Jan 25 '21 at 17:17
  • I don't expect the behavior to be different for Google, Facebook, Twitter. They should all work similarly in this regard. – jfriend00 Jan 25 '21 at 17:48

1 Answers1

4

First off, just use req.logout() by itself. Don't call req.session.destroy() and then inside of that try to call req.logout() (as the code in your question currently shows).

Then, when you go to your /auth/google google route the very first time, it will walk through an oauth session and you will have to confirm with Google that you are permitting this site to use your Google login via oauth.

When you then logout of your app, it is just killing your app login. It doesn't kill the Google login in that browser. That still remains. So, if you then go back to /auth/google, it just seamlessly (and without your further approval or participation) logs you back in as the currently logged in Google user. Google sees that you've previously approved this app to use your Google login and sees that the current browser is still logged into Google so it just approves the login without asking you again.

If you actually want your app to be able to login as a different Google user (or any other service using a similar mechanism), then you have log this browser out of Google itself or log in to Google itself as a different user or within Google revoke that app's permission to use the Google login. That will truly start you back at ground zero where you can login as a different Google user.

FYI, if you use your Google login with stackoverflow, you can experiment with this and see the very same behavior.

jfriend00
  • 683,504
  • 96
  • 985
  • 979