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.

Authenticate user by API Key on custom endpoints

default discord avatar
kaspartr3 years ago
22

I have created some custom endpoints but they are unprotected by default. How can I use Payload auth or user API keys to protect them?



I have gone through the following but they don't cover a custom endpoint case:


https://payloadcms.com/docs/authentication/config#doc

<-- only Collection based, not custom endpoint.



https://payloadcms.com/docs/authentication/overview#token-based-auth

<-- covers how to authenticate using JWT token, not API Key.



I have custom endpoints both on App level and Collection level. Neither seem to play nice with Payload authenticate middlewares when using API Keys.

  • default discord avatar
    math5363 years ago
  • default discord avatar
    kaspartr3 years ago

    I tried using middleware as in the examples, but putting API Key in the Authorization header as shown will not produce Payload to inject User object into the http request.

  • default discord avatar
    math5363 years ago

    you can get the user directly from mongodb



    create your own middleware to do this

  • default discord avatar
    kaspartr3 years ago

    Using the API Key? In this case, is it known what hashing algorithm Payload uses for Api keys?

  • default discord avatar
    math5363 years ago

    did you are using the API Key generated by admin panel, or jwt token?

  • discord user avatar
    dribbens
    3 years ago

    It is only the custom endpoints that are missing the

    req.user

    ?


    custom endpoints

    should

    hit the same middleware unless you have the

    root: true

    added and that is only an option outside of collections.



    I would verify that your requests work for the built-in collection endpoints to rule out that it is in fact an issue with the custom endpoints if you haven't already.



    You shouldn't have to write your own middleware. At worst you can import Payload's middleware but since that should already be running before your endpoint handler gets called, that won't fix your problem anyways.



    One common mistake with the authorization header is that payload recognizes:


    "Authorization: "JWT {token}"

    and not

    "Authorization: "bearer {token}"

    You can diagnose by comparing the admin UI requests in the network tab with how your app is calling Payload to find differences.


    @567578449439621124

    I hope some of this will help.

  • discord user avatar
    jmikrut
    3 years ago

    in addition, to authenticate via API key, here are the docs:



    https://payloadcms.com/docs/authentication/config#api-keys

    need a header like this:



    Authorization: MyCollectionSingularLabel API-Key 4iwj34li43jltij4
  • default discord avatar
    kaspartr3 years ago

    This does not work on custom endpoints. Adding the API-Key to the headers does not attach User object to HTTP request object on custom endpoints. At least that is my experience. Should it ?



    I am using the API Key

    not

    the token

  • discord user avatar
    dribbens
    3 years ago

    Yeah that is supposed to work. Do you want to create an issue on GitHub? I'd like to dig into this tomorrow.

  • default discord avatar
    kaspartr3 years ago

    Noted, will triple check this today before posting. Thank you.

  • discord user avatar
    dribbens
    3 years ago

    Nice, let me know. Happy to help

  • default discord avatar
    kaspartr3 years ago

    Perhaps the issue is with version. What is the latest stable Payload version?

  • discord user avatar
    dribbens
    3 years ago

    1.2.5



    I'm not aware of any recent changes on this though

  • default discord avatar
    kaspartr3 years ago

    Also as a note, my Collection does not have any auth params defined.



    Yes just tested again.


    Collection (non auth)


        {
          path: '/testing',
          method: 'post',
          handler: [
            async (req, res, next) => {
              console.log("/testing | user: ", req.user)
              if (req.user) next()
              else res.status(401).send({ error: "unauthorized" });
            }
          ]
        }


    Request


    http://localhost:3000/api/assets/testing
    Headers: Authorization: Asset API-Key <USER_API_KEY>


    req.user is undefined.

  • discord user avatar
    dribbens
    3 years ago

    Wait, what collection are you using for auth? in headers it looks like Asset instead of your users collection

  • default discord avatar
    kaspartr3 years ago

    I am requesting Assets not User.


    Flow:


    1) Create new user (enable API key) - this is a "system service" user.


    2) Create new collection "Assets"


    3) Put User API key to 3rd party service (Moralis)


    4) Have Moralis call Payload on the behalf of the user (using his API keys) to interact with Assets collection.

  • discord user avatar
    dribbens
    3 years ago

    Your flow makes sense, but that header needs to tell Payload what user collection the the API key belongs to, not what you're trying to query.

  • default discord avatar
    kaspartr3 years ago

    it works now, I'm stupid.

  • discord user avatar
    dribbens
    3 years ago

    Hahaha, no worries. Your not stupid

  • default discord avatar
    kaspartr3 years ago

    Thank for the help again 🙂

  • discord user avatar
    dribbens
    3 years ago

    Very welcome!

  • discord user avatar
    jmikrut
    3 years ago

    i love it when things work out



    haha



    catching up here

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.