Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Payload.authenticate method

default discord avatar
jeffreyartslast year
11

I'm working on a plugin where I'd like to verify the authenticated user via a socket io middleware method. For this I'd like to utilise the payload.authentication method. Could someone point me in the right direction? [The documentation](

https://payloadcms.com/docs/authentication/using-middleware

) on this method is rather limited,



I know that the

payload.authenticate

method expects middleware properties

(req, res, next)

, but since I am trying to use this method in a different environment as Express, I need to write some sort of wrapper. I'm just a bit puzzled what these values should be. I have the payload object at my disposal, as well as a socket object (which has its own req object among others).



Since I could not find anything in the docs, I dove into the codebase and found

/dist/auth/init.js

. Here can I see the inclusion of PassportJS's jwt strategy, which expects a

ctx

object of which it seems to be using the

collections

,

config

&

secret

properties. Properties, so I've found in

dist/initHTTP.js

, that are properties of the

payload

object. However, simply replacing the request object with the payload object doesn't (seem to) work.


io.use((socket, next) => {
  const auth = payload.authenticate(payload, socket.data, next)
})

Is there someone who can point me in the right direction for how to re-use the same method as Payload uses to authenticate the user? Or should I refrain from this approach entirely, and just use PasportJS's directly? Any ideas & suggestions are welcome :D!



Payload.authenticate method

  • default discord avatar
    vpjmlast year

    I am also very interested by this post. I hope someone will take the time to write a comprehensive response so that we can finally clear up any doubts about authentication on payload

    :plus1:

    .

  • default discord avatar
    notchrlast year
    @703162911241273394

    Where are you calling .authenticate() ? Before or after the payload initialization?

  • default discord avatar
    jeffreyartslast year

    I believe it was in the config.onInit method of a plugin

  • default discord avatar
    notchrlast year

    Are you able to check it out? Happy to help troubleshoot



    The authenticate method should happen after payload is initialized

  • default discord avatar
    jeffreyartslast year

    Well, I have refactored the code many times and currently got rid of it entirely (for now).


    Nonetheless, I don't think I am following your argument. How I understand it, is that socketIO implements the payload.authenticate(payload, socket.data, next) method as [a function that gets executed for every incoming connection](

    https://socket.io/docs/v4/middlewares/

    ). How is the position of this declaration relevant for the operation of the middleware function?



    I think that if I'd understand that, I might also be able to figure out why I can't share sessions between socketIO & express (since that is also being handled via middleware)

  • default discord avatar
    notchrlast year

    I'm going by the warning on that page



    Payload must be initialized before the payload.authenticate middleware can be used. This is done by calling payload.init() prior to adding the middleware.


      await payload.init({
        secret: 'PAYLOAD_SECRET_KEY',
        express: app,
      })
    
      const router = express.Router()
    
      // Note: Payload must be initialized before the `payload.authenticate` middleware can be used
      router.use(payload.authenticate) 
  • default discord avatar
    jeffreyartslast year
    https://socket.io/docs/v4/middlewares/#compatibility-with-express-middleware

    This is also relevant information; Should try this once.



    io.engine.use((req, res, next) => {
      const isHandshake = req._query.sid === undefined;
      if (isHandshake) {
        payload.authenticate(req, res, next);
      } else {
        next();
      }
    })
  • default discord avatar
    notchrlast year

    Shouldnt next be called in both conditions?

  • default discord avatar
    jeffreyartslast year

    What do you mean? next()

    is

    being called in both conditions. Payload.authenticate calls that method interenally



    Just made an important/relevant discovery. The authentication process doesn't work how I thought it did. I thought it was done via the "Authentication" header, but in fact it occurs via cookies. I'm not familiar with that process, so I would need to dive into it a but further before jumping to conclusions. But surely this misunderstanding from my part will be at the core of a lot of other concepts around authentication and sessions that I couldn't put my finger on



    ### A summary of insights



    - payload.authenticate does not have to be included manually, despite [this documentation](

    https://payloadcms.com/docs/authentication/using-middleware

    ) says it is mandatory to do.


    - Payload uses cookies that are not accessible by JS to manage authentication. These cookies are not sent by default but should be added manually in the front-end application


    - Whenever you ended up in a crashing Webpack loop you're fucked. While it can help to remove the

    node_modules/.cache

    directory, it is in no way a guaranteed solution.



    ------------



    This topic has become a true mess 😅, so I will mark it as solved since it no longer has a clear question that requires a clear answer 🙂

  • default discord avatar
    ritsu0455last year

    Have you tried 3.0? It's a

    lot

    better here. 0 dependency to some HTTP interface, you can call

    payload.authenticate

    even within a script.

  • default discord avatar
    jeffreyartslast year

    I have not, but good to hear that this method has become more accessible

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.