DEV Community

Chris Nowicki
Chris Nowicki

Posted on

How to Secure Vercel Cron Job routes in NextJS 13

Lee Robinson from Vercel recently responded to a question I had about securing cron job routes:

Use Case

Secure your cron job routes so that they can't be run by just anyone with the known route. We want to make sure that ONLY Vercel can run the cron job from their servers. We do this by adding CRON_SECRET to our env variables. If present, vercel will automatically send this as a bearer token in the header, as Lee mentioned in his response to me:

"If present, the HTTP request to the cron endpoint will contain an authorization header with it as a value, like this: "Authorization: Bearer $CRON_SECRET".

At the end of this tutorial I will show you how to configure Postman so that you can test your route with the Bearer Token.

Assumptions

  1. You are familiar with nextJS 13/React Frameworks
  2. You are familiar with Vercel and where to find the Environmental Variables in your project settings
  3. If you do not know how to setup a cron job then read my tutorial here first and the return to this article to learn how to secure it.

Let's Secure a Cron Job! 🔒

  1. Create a Secret Key

    • In your terminal type openssl rand -hex 32
    • You should have an output of something like this:

    console response

  2. Add the CRON_SECRET variable to your local .env file with the value that is displayed in your terminal from step 1 above.

  3. Modify the code in your cron job route to look for the bearer token. If it doesn't exist then return an unauthorized response with 401 status code:

    import { NextRequest, NextResponse } from 'next/server'
    
    export async function GET(req: NextRequest) {
      // get the bearer token from the header
      const authToken = (req.headers.get('authorization') || '')
        .split('Bearer ')
        .at(1)
    
      // if not found OR the bearer token does NOT equal the CRON_SECRET
      if (!authToken || authToken != process.env.CRON_SECRET {
        return NextResponse.json({ error: 'Unauthorized' }, { 
        status: 401 })
      }
      // if token exists then move on with the cron job
      ...
    }
    
  4. Test to make sure it worked by going to the route in your browser. You should receive a json error message, "Unauthorized":

    browser response with error

  5. Add the CRON_SECRET variable to the vercel project settings Environment Variables as seen below:

    vercel project settings

  6. Deploy your project to Vercel and test on your live site. You should receive a json error message "Unauthorized":

    browser response

CONGRATULATIONS! 🎉, Your cron job route is now secured! Now, let's setup Postman so you can test your cron job with the bearer token.

Setup POSTMAN

NOTE: This is not a tutorial on how to install postman, setup a workspace, etc.. There are lots of resources out there. Here is a good one on YouTube.

  1. Select the plus icon to add a GET request:

    postman setup get request

  2. Add in your route and select Send. You should see the same unauthorized response in the response as you did from when we tested in the browser:

    add info to postman

  3. Select Auth, Select the drop down arrow under Type and select Bearer Token. Enter the value of the CRON_KEY in the Token Field.

    add auth info to postman

  4. Once all the info is entered select Send to test the route with the Bearer token and you will get the expected return value of the cron job:

    postman response

Conclusion

I hope you found this helpful! Please let me know if you have any questions and I will do my best to respond!

Top comments (0)