Closed joostwmd closed 6 months ago
Supabase Auth does not deal with provider refresh tokens. You can access them as documented here: https://supabase.com/docs/reference/javascript/auth-onauthstatechange?example=store-provider-tokens
For refreshing the provider tokens, please follow the documentation from Spotify.
I'd like to request that this issue be reopened and re-evaluated as I am also running into the issue where attempting to refresh the token with Spotify fails with error "{error: 'invalid_request', error_description: ''}
after initially signing on with supabase.auth.signInWithOAuth()
.
I believe the reason for closing this issue, that Supabase Auth does not deal with provider refresh tokens, is inapplicable because the original reporter is specifically attempting to refresh the token themselves and is not relying on Supabase to do so, so Supabase Auth not dealing with provider refresh tokens is irrelevant.
Furthermore, I can corroborate that adding the client_secret
causes the refresh token request to succeed, whereas not including it causes the request to fail with the above error (though I did it by adding a client_secret
parameter to the request body, whereas @joostwmd did so by appending it to the Authorization header).
Finally, I can confirm that using the same demo repository above, I am able to successfully refresh the token even without including the client_secret on either the request body or the Authorization header:
This would seem to corroborate the suspicion that somehow, Supabase's OAuth login is not utilizing the PKCE flow correctly, causing Spotify to treat this sign in as an implicit flow rather than a PKCE flow, thus requiring a client_secret
to refresh the token.
This is problematic for any browser-based or mobile application that solely uses Supabase for OAuth for Spotify, because such applications cannot safely include the client_secret
, which prevents token refreshing entirely. Presumably, other OAuth providers do not suffer from this issue, since it seems like tests are included which verify PKCE functionality (for example, here). However, no such tests are available for Spotify, which would further seem to indicate that it's possibly behaving differently somehow.
Thanks ahead of time for any guidance anyone can provide. 🙏
cc @hf
Bug report
Describe the bug
I am using Spotify as an oAuth provider in my app. I can sign in via the PKCE flow, but i am unable to refresh the spotify oAuth token, following the official spotify documentation.
this is my implementation according to the spotify docs:
with this i am getting an error 400 along with an empty error message.
"{error: 'invalid_request', error_description: ''}
After a lot of playing around i found out that setting an Authorization header like this
Authorization: 'Basic ' + btoa(client_id + ':' + client_secret)
makes it possible to refresh the token. However, doing it like this exposes the client secret in the browser, but the idea behind the about PKCE flow is that you don't have to do that. The spotify documentation also don't mention that you have to pass the client secret in the PKCE flow. But it is required for the normal (no PKCE) Authorization Code flow. This is where i started to suspect that supabase might not use the PKCE flow as intended.Then i decided to set up the pkce flow without supabase, to check if the error might be on Spotifys side. I cloned this repo and i was able to refresh the token without providing my client secret, so the Spotify API works.
That leaves only supabase in the equation. I think the issue is that when sining in via supabase oAuth, something happens under the hood, that makes the provider think you are not using the PKCE flow. At least that could explain, why i am forced to supply my client secret when refreshing the token later.
To Reproduce
Steps to reproduce the behavior, please provide code snippets or a repository:
I tried it in both sveltekit and react native, both with the same results.
SVELTEKIT
In sveltekit i am initializing the supabase client like this:
here is the sign in function
and here i am extracting the code from the callback url and exchanging it against a token
React Native
In my React Native App i am initializing my supabase client like this:
here is the sign in function:
and here is how i handle the callback url and extract the code + exchange it for a session
This is not exactly the way it is shown in the docs, but this is intended.
The Sign In works as expected but calling the refreshToken function during an active session results in the error. I know that it isnt an error from wrong credentials like the client id or refresh token because this produces related error messages, but i am receiving an empty string. Also when adding the Authorizaiton header and changing nothing else, i can refresh the token, so wrong credentials are not the cause of this error
To reproduce the vanilla js PKCE flow, you can just clone this repo and use your client id and url
Expected behavior
Being able to refresh the provider token after sining in via supabase using the PKCE flow