fastify / help

Need help with Fastify? File an Issue here.
https://www.fastify.io/
64 stars 8 forks source link

Passport calls registerUserDeserializer on every static file request #1036

Closed clubside closed 2 months ago

clubside commented 3 months ago

I am using Fastify Passport to handle Google logins to the site. Everything works great except for the fact that every request for a static file by a logged-in user passes through registerUserDeserializer.

app.register(fastifyPassport.initialize())
app.register(fastifyPassport.secureSession())
app.register(fastifyStatic, {
    root: path.join(__dirname, 'public')
})

fastifyPassport.registerUserSerializer(
    async (user, request) => {
        console.log('registerUserSerializer', { user }, { json: user._json })
        const userJson = user._json
        const { id, displayName } = user
        const userForSession = { id, displayName, email: userJson.email }
        // User object sent it from Google.
        // Here you want to call your DB and get the user info from there and store it in the session.
        // The session is encrypted but if you dont want to store all the user info in the session just store the DB id in the session
        return userForSession
    }
)

fastifyPassport.registerUserDeserializer(async (userFromSession, request) => {
    console.log('registerUserDeserializer', { userFromSession })
    // Here you decrypt the session object and read the user info from there.
    // If the whole user object is stored just return it. If only an ID is stored, look up the user in the DB using the ID and return that user
    return userFromSession
})

Here are some sample log lines from the server when a user is logged it. I assume the non-304 ones are the ones triggering registerUserDeserializer.

registerUserDeserializer {
  userFromSession: {
    id: '117273030782572725336',
    displayName: 'Chris Rowley',
    email: 'clubside360@gmail.com'
  }
}
registerUserDeserializer {
  userFromSession: {
    id: '117273030782572725336',
    displayName: 'Chris Rowley',
    email: 'clubside360@gmail.com'
  }
}
registerUserDeserializer {
  userFromSession: {
    id: '117273030782572725336',
    displayName: 'Chris Rowley',
    email: 'clubside360@gmail.com'
  }
}
registerUserDeserializer {
  userFromSession: {
    id: '117273030782572725336',
    displayName: 'Chris Rowley',
    email: 'clubside360@gmail.com'
  }
}
07/06/24 03:38:54  info: #req-v ←GET:/css/style.css request from ip ::1 (fastify-request-logger)
07/06/24 03:38:54  info: #req-w ←GET:/css/features.css request from ip ::1 (fastify-request-logger)
07/06/24 03:38:54  info: #req-x ←GET:/img/icons/hamburger.svg request from ip ::1 (fastify-request-logger)
07/06/24 03:38:54  info: #req-v →GET:/css/style.css response with a 304-status took 8.730ms (fastify-request-logger)
07/06/24 03:38:54  info: #req-w →GET:/css/features.css response with a 304-status took 6.456ms (fastify-request-logger)
07/06/24 03:38:54  info: #req-y ←GET:/img/icons/cape.svg request from ip ::1 (fastify-request-logger)
07/06/24 03:38:54  info: #req-x →GET:/img/icons/hamburger.svg response with a 304-status took 7.875ms (fastify-request-logger)
07/06/24 03:38:54  info: #req-y →GET:/img/icons/cape.svg response with a 304-status took 4.090ms (fastify-request-logger)

Your Environment

mcollina commented 3 months ago

You need to use encapsulation:

app.register(async function (app) {

app.register(fastifyPassport.initialize())
app.register(fastifyPassport.secureSession())

fastifyPassport.registerUserSerializer(
    async (user, request) => {
        console.log('registerUserSerializer', { user }, { json: user._json })
        const userJson = user._json
        const { id, displayName } = user
        const userForSession = { id, displayName, email: userJson.email }
        // User object sent it from Google.
        // Here you want to call your DB and get the user info from there and store it in the session.
        // The session is encrypted but if you dont want to store all the user info in the session just store the DB id in the session
        return userForSession
    }
)

fastifyPassport.registerUserDeserializer(async (userFromSession, request) => {
    console.log('registerUserDeserializer', { userFromSession })
    // Here you decrypt the session object and read the user info from there.
    // If the whole user object is stored just return it. If only an ID is stored, look up the user in the DB using the ID and return that user
    return userFromSession
})

})

app.register(fastifyStatic, {
    root: path.join(__dirname, 'public')
})
clubside commented 3 months ago

@mcollina I wrapped all of my Fastify objects with in the app.register(async function (app) { }) except for app.listen() and am still getting the same result.

mcollina commented 2 months ago

As I put in the code above, you need to have fastifyStatic registered outside.

clubside commented 2 months ago

Sorry I missed that @mcollina that fixed everything, thanks so much!