mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 09:55:06 +03:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update ## What is the current behavior? We don't have a guide on how to manage 401 errors in edge functions ## What is the new behavior? Adds guide ## Additional context I noticed that pre-existing guides have the following header: ```sh database_id = "4e6ff2e4-2abb-4fba-8233-5883b3d56fb0" ``` Not sure if the database_id will be added when a guide is introduced manually. @charislam, does anything special need to be done? --------- Co-authored-by: Chris Chinchilla <chris.ward@supabase.io> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Chris Chinchilla <chris@chrischinchilla.com>
162 lines
5.2 KiB
Plaintext
162 lines
5.2 KiB
Plaintext
---
|
|
title = "Edge Function 401 error response"
|
|
topics = [ "functions" ]
|
|
keywords = [ "401", "error" ]
|
|
|
|
[[errors]]
|
|
http_status_code = 401
|
|
message = "Invalid JWT"
|
|
---
|
|
|
|
The function rejected the request for lacking the appropriate authorization headers.
|
|
|
|
## Context for the error
|
|
|
|
#### The JWT verification check
|
|
|
|
By default, edge functions are configured to check requests for a valid [legacy key](/docs/guides/api/api-keys#overview).
|
|
|
|
#### How the check causes 401 errors
|
|
|
|
The check fails and return a 401 permission error if:
|
|
|
|
- The request includes an invalid legacy key, or
|
|
- The request uses the newer asymmetric keys instead of a legacy key.
|
|
|
|
#### What this check actually does
|
|
|
|
This validation provides limited security value. It only confirms that the request includes a legacy token associated with your project, such as the anon key.
|
|
|
|
It does not validate the user's identity or permissions beyond that.
|
|
|
|
Because the security check is weak, it was deprecated when used with the new asymmetric keys.
|
|
|
|
## Solving the error
|
|
|
|
### Step 1: Identifying the error
|
|
|
|
<Admonition type="note">
|
|
|
|
If the tests return a 401 but don't match the criteria below, the error is coming from your app logic, not the JWT check.
|
|
|
|
</Admonition>
|
|
|
|
### Inspecting the return message
|
|
|
|
When an edge function fails due to a platform 401 error, it returns the error:
|
|
|
|
```json
|
|
{
|
|
"code": 401,
|
|
"message": "Invalid JWT"
|
|
}
|
|
```
|
|
|
|
### Inspecting the logs
|
|
|
|
Your code may return a 401 error due to its own logic
|
|
|
|
```js
|
|
return new Response(JSON.stringify(data), {
|
|
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
|
status: 401, // app logic returning a 401
|
|
})
|
|
```
|
|
|
|
A 401 status code alone doesn't confirm a JWT check failure by itself. The log must also lack an `execution_id`.
|
|
|
|

|
|
|
|
Instead of manually reviewing the logs, you can run the below query in the [log explorer](</dashboard/project/_/logs/explorer?q=SELECT+DISTINCT%0A++++req.pathname+AS+function_name,%0A++++res.status_code%0A++FROM+function_edge_logs%0A++CROSS+JOIN+UNNEST(metadata)+AS+metadata+%0A++CROSS+JOIN+UNNEST(metadata.request)+AS+req+%0A++CROSS+JOIN+UNNEST(metadata.response)+AS+res+%0AWHERE+status_code+=+401+AND+metadata.execution_id+IS+NULL%0ALIMIT+10;&its=&ite=%3E>) to get a list of functions that were impacted by the check:
|
|
|
|
```sql
|
|
select distinct
|
|
req.pathname as function_name,
|
|
res.status_code
|
|
from
|
|
function_edge_logs
|
|
cross join UNNEST(metadata) as metadata
|
|
cross join UNNEST(metadata.request) as req
|
|
cross join UNNEST(metadata.response) as res
|
|
where status_code = 401 and metadata.execution_id is null
|
|
limit 10;
|
|
```
|
|
|
|
### Step 2: Disabling the JWT check
|
|
|
|
The JWT check provides minimal security benefits, so we now recommend handling authentication through app logic instead. See the [Edge Function Auth Doc](/docs/guides/functions/auth) for details.
|
|
|
|
If you've migrated to [asymmetric keys (publishable/secret)](/dashboard/project/_/settings/api-keys) or no longer need the JWT check, you can disable it using one of the three options below:
|
|
|
|
<Accordion
|
|
type="default"
|
|
openBehaviour="multiple"
|
|
chevronAlign="right"
|
|
justified
|
|
size="medium"
|
|
className="text-foreground-light mt-8 mb-6"
|
|
>
|
|
<div className="border-b mt-3 pb-3">
|
|
<AccordionItem
|
|
header="In the Dashboard"
|
|
id="item-1"
|
|
>
|
|
In the [Function Dashboard](/dashboard/project/_/functions/), under the offending function's detail tab, you can toggle off the check:
|
|
|
|

|
|
|
|
|
|
</AccordionItem>
|
|
|
|
</div>
|
|
<div className="border-b mt-3 pb-3">
|
|
<AccordionItem
|
|
header="With the Management API"
|
|
id="item-2"
|
|
>
|
|
|
|
1. Generate a secret token in the [Account Preferences Dashboard](/dashboard/account/tokens)
|
|
2. Get your project ID from the [General Settings](/dashboard/project/_/settings/general)
|
|
3. Substitute in the `PROJECT_ID`, `FUNCTION_NAME`, and `SECRET_TOKEN` in below [management endpoint](/docs/reference/api/v1-update-a-function). Then execute the request from a terminal environment
|
|
|
|
```sh
|
|
# remember to substitute in your PROJECT_ID, FUNCTION_NAME, and SECRET_TOKEN
|
|
|
|
curl 'https://api.supabase.com/v1/projects/PROJECT_ID/functions/FUNCTION_NAME?verify_jwt=false' \
|
|
--request PATCH \
|
|
--header 'Content-Type: application/vnd.denoland.eszip' \
|
|
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
|
|
--data '""'
|
|
|
|
````
|
|
</AccordionItem>
|
|
|
|
</div>
|
|
|
|
<div className="border-b mt-3 pb-3">
|
|
<AccordionItem
|
|
header="With the Supabase CLI"
|
|
id="item-3"
|
|
>
|
|
|
|
With the [Supabase CLI](/docs/guides/local-development/cli/getting-started), you can redeploy your edge function without the JWT check:
|
|
|
|
```sh
|
|
supabase functions deploy hello-world --no-verify-jwt
|
|
```
|
|
|
|
</AccordionItem>
|
|
|
|
</div>
|
|
</Accordion>
|
|
|
|
If you would like to continue using the JWT check, make sure that your [Supabase Client](/docs/guides/api/rest/client-libs) only uses your [legacy keys](/dashboard/project/_/settings/api-keys/legacy).
|
|
|
|
## Additional resources
|
|
|
|
- [Securing Edge Functions](/docs/guides/functions/auth)
|
|
- [Debugging Edge Functions](/docs/guides/functions/logging)
|
|
- [Quickstart Deployment: Dashboard](/docs/guides/functions/quickstart-dashboard)
|
|
- [Quickstart Deployment: CLI](/docs/guides/functions/quickstart)
|
|
````
|