How to Secure Vercel Cron Job routes in NextJS 13
Tags: nextjs, cronjob, vercel, security
Published: 2023-09-27 18:02:04

---
title: How to Secure Vercel Cron Job routes in NextJS 13
published: true
description: Tutorial on how to secure a vercel cron job in NextJS 13.
tags: NextJS, CronJob, vercel, security
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-09-27 16:10 +0000
---

[Lee Robinson](https://twitter.com/leeerob) from [Vercel](https://www.vercel.com) recently responded to a question I had about securing cron job routes:

{% twitter 1690055690834845703 %}

## 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](https://www.postman.com) 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](https://dev.to/chrisnowicki/how-to-create-a-vercel-cron-job-using-nextjs-13-2amb) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1jq2guo34kh7orb1r3uw.png)

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:
    ```js
    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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1f5e0hgamm4ceriu8whz.png)

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

    ![vercel project settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lo8mz1ohbtgpzb0cx87c.png)

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

    ![browser response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ruhn53j0k4bhrb8sfjf.png)

**CONGRATULATIONS! 🎉**, Your cron job route is now secured!  Now, let's setup [Postman](https://www.postman.com) 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](https://www.youtube.com/watch?v=VywxIQ2ZXw4). 

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

    ![postman setup get request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flujduda4qbcc0omkri6.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/415nyfwaeklm8hja8n7z.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvkoevxosg9y4izew7bz.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dgqky2aku4qm4ljuon75.png)

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