Description
Bug report
- 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
The graphql endpoint for my project returns 401 {"message":"invalid signature"} when I use any user's session access_token as described in the docs. I can access the graphql endpoint from the https://supabase.com/dashboard/project//api/graphiql when impersonating that user.
To Reproduce
- Create user in db
- Setup Javascript client to call graphql
- Call api
JS code
const apiKey = process.env.SUPABASE_ANON_KEY
const Authorization = options.graphqlToken
// call the graphql endpoint
console.log('Authorization', Authorization)
console.log('apiKey', apiKey)
let response
try {
response = await fetch(options.graphqlPath, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization,
apiKey
},
body: JSON.stringify({
query: gqlQuery,
variables,
}),
})
} catch (err) {
console.error(`Failed to fetch from ${options.graphqlPath}. Err: `, err)
throw new BadGateway()
}
if (response.status != 200 && response.status != 201) {
// Proxied endpoint call unsuccesful, exit
const body = await response.text()
console.error(
`Failed to call query endpoint! graphqlPath: ${options.graphqlPath}
Status code: ${response.status}
Token length: ${options.graphqlToken.length}
Headers: ${JSON.stringify(response.headers)}
Response body: ${body}`,
)
throw new BadGateway()
output is
Authorization Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6Img4clRmbnZseG1xdjY1dXYiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzExOTg5Mzc4LCJpYXQiOjE3MTE5ODU3NzgsImlzcyI6Imh0dHBzOi8va2FiY2x5eGVzb2h1a293d3p3aWIuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6IjE0MzgxMDkyLTBiMzgtNGUwMS1iNDYxLWM4MzNlYWVhMGI2YiIsImVtYWlsIjoiZXhhbXBsZUBlbWFpbC5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxMTk4NTc3OH1dLCJzZXNzaW9uX2lkIjoiNGUxOWQ1NGYtODk2OC00ODEzLWFmOTAtYTYyMDdmMjA5YTZiIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.b5wOckaqQG020IRdLZ3QI6XOT7hHHy-I_Xjx3weor70
apiKey <hidden>
Failed to call query endpoint! graphqlPath: https://api.supabase.com/platform/projects/<project>/api/graphql
Status code: 401
Token length: 705
Headers: {}
Response body: {"message":"invalid signature"}
BadGateway [Error]
Expected behavior
I expect to have the endpoint returns the graphql.
Screenshots
If applicable, add screenshots to help explain your problem.
System information
- OS: MacOS 14.4
- Version of supabase-js: 2.39.3
- Version of Node.js: 18.17.1
Additional context
Where is the "invalid signature" message generated? I looked through supabase, supabase-js, auth, auth-js, auth-helpers, pg_graphql, github.com/golang-jwt/jwt, https://pkg.go.dev/go.imperva.dev/demos/matrix-chat/internal/api/demo#ParseJWTClaims, and I could not find where that string is generated and where the 401 is returned.
The token shown above appears valid per the online jwt decoder at https://10015.io/tools/jwt-encoder-decoder as it's decoded as
{
"aud": "authenticated",
"exp": 1711989378,
"iat": 1711985778,
"iss": "https://<projectid>.supabase.co/auth/v1",
"sub": "14381092-0b38-4e01-b461-c833eaea0b6b",
"email": "[email protected]",
"phone": "",
"app_metadata": {
"provider": "email",
"providers": [
"email"
]
},
"user_metadata": {},
"role": "authenticated",
"aal": "aal1",
"amr": [
{
"method": "password",
"timestamp": 1711985778
}
],
"session_id": "4e19d54f-8968-4813-af90-a6207f209a6b",
"is_anonymous": false
}
JWT Header
{
"alg": "HS256",
"kid": "h8rTfnvlxmqv65uv",
"typ": "JWT"
}
Separately, the docs are quite inconsistent about which headers and keys are required and the endpoints.
Relay example https://supabase.com/docs/guides/graphql/with-relay shows
fetch(`${SUPABASE_URL}/graphql/v1`
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${session?.access_token ?? SUPABASE_ANON_KEY}`,
Apollo example shows no apiKey header nor vallbck to anon key.
const token = (await supabase.auth.getSession()).data.session?.access_token
return {
headers: {
...headers,
Authorization: token ? `Bearer ${token}` : '',
},
Quickstart docs at https://supabase.com/docs/guides/graphql also show /v1
in the url but my project's url clearly has no /v1
https://supabase.com/dashboard/project/<projectid>/api/graphiql
. The quickstart docs link have a broken link to api, https://supabase.com/docs/guides/graphql#api-key-api_key
The graphiql explorer doesn't show the apiKey in the Headers section.
The graphql query that the explorer makes doesn't show the apiKey header.