Invalid API key Double check your Supabase `anon` or `service_role` API key
thecode-master-sy opened this issue · comments
Bug report
I get this error when i am trying to use the supabase broadcast to send messages to a channel, at first it was working but as of recently i start seeing this error, how do i resolve this please.
my supabase anon key and url are loaded properly, its working for auth but for realtime it fails
how to repelicate:
const supabase = createClientComponentClient();
channel.send({ type: 'broadcast', event: 'message', payload: newMessage, })
error i am getting
{ "message": "Invalid API key", "hint": "Double check your Supabase
anonor
service_role API key." }
- I confirm this is a bug with Supabase, not with my own application.
- I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior, please provide code snippets or a repository:
- Go to '…'
- Click on '…'
- Scroll down to '…'
- See error
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
System information
- OS: [e.g. macOS, Windows]
- Browser (if applies) [e.g. chrome, safari]
- Version of supabase-js: [e.g. 6.0.2]
- Version of Node.js: [e.g. 10.10.0]
Additional context
Add any other context about the problem here.
@thecode-master-sy can you share what's going on inside createClientComponentClient()
? also, can you submit a support ticket and share your project ref so we can take a look at your project's specifics?
createClientComponentClient() is coming from supabase-nextjs/authhelpers package
@w3b6x9
I am also facing the same issue, channel.send
returns error
string, then I intercepted the network request and noticed that
https://<ID>.supabase.co/realtime/v1/api/broadcast
is returning 401 with the following error.
![image](https://private-user-images.githubusercontent.com/22298895/295676891-b9fb64ad-1ee9-40bb-b62a-68a465475f91.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDc0MzIyMDMsIm5iZiI6MTcwNzQzMTkwMywicGF0aCI6Ii8yMjI5ODg5NS8yOTU2NzY4OTEtYjlmYjY0YWQtMWVlOS00MGJiLWI2MmEtNjhhNDY1NDc1ZjkxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAyMDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMjA4VDIyMzgyM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTVmMDEwZDc4YzU5ZWU4ZjFjZmJhYTAwOTE0OGYwYTI5YmJlNWZhZjQxZGRkMzQ1YTljMDIwYTQ4OTk3ODA0ZjYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.zQ5pRnJwGgPkUOj03gVFmKSXxGhADY1nsFm-w0KU8uU)
Library version: @supabase/supabase-js: ^2.39.2
Environment: React Native (Expo)
I followed the supabase documentation, everything is working fine including realtime websocket connection. WSS is connected with the same apikey and access token and it is receiving events. No issues at all.
The only issue is with channel.send
which is using REST api instead of websockets and that returns 401, I did not modify or overriding anything, just followed the documentation and when I debugged via network interceptor /api/broadcast REST api has got the same apikey and accesstoken sent as a Cookie
UPDATES:
After further debugging I noticed that accessToken
was sent as an apikey
to /api/broadcast
endpoint but it expects only anon
or service role
tokens as a valid token, after manually changing apikey
to anon key and re-send the same request using cURL it worked as expected
Found the bug and raised PR:
The issue seems to be here in this line in realtime-js package. this.socket.accessToken
gives user's accessToken
not anon key
, therefore that endpoint is returning 401
PR: #273
@Mukhammadali For now, you can force the anon_key:
supabase.realtime.accessToken = env.SUPABASE_ANON_KEY!; const channel = supabase.channel('channel') channel.send({ type: 'broadcast', event: 'example', payload: { }, })
@Mukhammadali For now, you can force the anon_key:
supabase.realtime.accessToken = env.SUPABASE_ANON_KEY!; const channel = supabase.channel('channel') channel.send({ type: 'broadcast', event: 'example', payload: { }, })
be careful with this move as it can break Realtime Postgres Changes listening when tables have RLS enabled and policies set.
realtime-js
will send to Realtime server the new token set, in this case anon
token, during the next heartbeat which could prevent new database changes from reaching the client depending on your rls policies.
we're also aware of this issue. the problem here is that the accessToken
gets updated to user's authenticated
token and our API gateway won't allow it as we're hard checking against your project's anon
and service_role
tokens when hitting the broadcast endpoint.
@Mukhammadali thanks, it's a good stopgap until we decide on how we wanna do it in our API Gateway.
this should be addressed in realtime-js v2.9.2. thanks for all your feedback!