payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
28.15k stars 1.74k forks source link

Nested relationship data missing in JWT token and req.user #1361

Closed dsod closed 2 years ago

dsod commented 2 years ago

Bug Report

Current Behavior

The JWT token created in the default login operation does not contain nested relationship data. This is usually okay, due to the passport JwtStrategy middleware fetching the user from DB (with nested data) on every request. The issue is static assets, where we still perform the DB query for the user, but the nested data is not populated.

The two issues I see with this are:

  1. The read access control lacks nested relational data when run for static asset requests
  2. Inefficient (redundant DB calls)

Expected Behavior

The data provided through req.user should contain the same data for document and static asset requests. Furthermore, I think it would be a good idea to retrieve the user state from the JWT token, instead of the DB.

Possible Solution

If the JWT token is populated correctly, we could use it's state in the JwtStrategy to populate req.user, which would solve the issue with static assets. Although, I see a few problems with the current login operation:

In order to populate the JWT token properly, the afterRead hook (which effectively is the function that populates the nested data into the user object) should be moved up before the assignment of the token. The req.user assignment also needs to be moved up then, so that the afterRead passes the user state to access control functions.

When the JWT contains all the data that a fresh DB query would return, we should be able to simply re-use it's state. The only downside I can see when doing this would be that a new JWT token would have to be generated (i.e by logging out and in again) in order for the state to be updated. So, changes in the JWT state would not be reflected immediately.

Steps to Reproduce

See tests in the PR: 1362

Detailed Description

Payload version: 1.1.21

jmikrut commented 2 years ago

Hey @dsod I know we've got a conversation going on Discord regarding populating req.user straight from the JWT. I am not opposed to this, and I think we should keep that conversation going. But for now, I've fixed this original issue and we can keep the conversation going either on Discord or on the PR that you've opened!

dsod commented 1 year ago

Thanks!

github-actions[bot] commented 2 months ago

This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.