#How to handle authentication on custom API routes

27 messages · Page 1 of 1 (latest)

proud abyss
#

I have one additional API route which starts an import proces. The route is configures in the global Payload config:

    express: {
        postMiddleware: [importAccess],
    },
    endpoints: [
        {
            path: "/import/run/:collection",
            method: "get",
            handler: importHandler,
        },
    ],

Most works as expected, but i can't seem to get access control working within the middleware or route itself. What i would like to do is call a generic "isAdmin" function (which i already use in other places) on an user object. But the user variable within the request is always undefined. A workaround was loading the import global collection which as access control on it. According to the documentation, access control should be invoked when using req.payload.findGlobal but this is not the case. The collection object is always returned when calling the custom API route. Calling the normal API route for this collections results in a 403 error as expected.

What is the correct way to handle this? Thanks.

green seal
#

Did you call payload.authenticate() after payload.init()?

#

undefined users in the cb seem related to that common issue

#

router.use(payload.authenticate);

proud abyss
#

There seems to be a type error: throw new TypeError('Router.use() requires a middleware function')

#

Also, i am configuring my routes within the payload config, not directly in Express, you should say the authentication is already invoked.

green seal
#

Hmmm

#

They say that the req object applies access control

ember dirge
#

As you guys already pointed out, the authentication middleware should be called for you before your custom endpoints are called.

#

Since you are using postMiddleware that is going to be called at the very end, but it seems to me you would want to get your access control handled first as preMiddleware

proud abyss
#

This is strange, it worked for a couple of minutes (had a user object within the response) and now its gone again...

ember dirge
#

To simplify why you have you, you could do this instead:
handler: [importAccess, importHandler],

proud abyss
#

@ember dirge, i also tested with preMiddleware but that made no difference.

#

I will try that

ember dirge
#

Yeah, it shouldn't matter

#

well...

#

preMiddleware means you won't have req.user assigned yet

#

postMiddleware should have req.user as well as the suggestion I made with the handler: [accessImport, importHandler]. This is probably not going to fix your issue.

proud abyss
#

Thats sound logical.

#

It seems to work with the handler and middleware together. Will investigate what went wrong there.

ember dirge
#

That is interesting! I'm glad it works for you. There could be a bug in globals postMiddleware or something else going on that is specific to your project.

sinful junco
# proud abyss Ah, i will test that, the official documentation states that authentication is a...

I think there might be a misunderstanding here. The docs say:

req will have the payload object and can be used inside your endpoint handlers for making calls like req.payload.find() that will make use of access control and hooks.
I think you have to read it like this: "can be used for making calls that can make use of access control and hooks"
From how I understand it, there is no magic that automatically tells the payload instance what the currently processed req and subsequently req.user object is. So in order to make use of access control for the local api you have to pass in the req object to payload.find which is also what for example the find handler does: https://github.com/payloadcms/payload/blob/master/src/collections/requestHandlers/find.ts#L24e

sinful junco
#

Just realized the handler is not actually itself using the local api 🤦‍♂️. Doesn't change the matter, though. You'll have to provide req and overrideAccess:false to local api for access control mechanisms to be used.

twin cargo
#

@sinful junco I have a similar question, I'd trying to persist req attributes from my custom endpoint (in this case a gql query) but they disappear in lower level local API calls. I tried passing req into the find call but got an error. Were you able to solve this?