Bug: OAuth Callback Authorization Error on Sign-in
Describe the bug
Description
I encountered an authorization error when attempting to sign into Badget.io using OAuth. The callback URL returned an "Unauthorized request" error, preventing login.
Steps to Reproduce
- Navigate to Badget.io and initiate the sign-in process.
- Complete the OAuth consent screen.
- Encounter the error on the callback.
Expected Behavior
The OAuth process should complete successfully, and I should be logged into the system.
Actual Behavior
An error message is displayed stating "Unauthorized request," and I am unable to log in.
Error Messages
- Message: Unauthorized request
- Long Message: You are not authorized to perform this request
- Error Code: authorization_invalid
Additional Information
- Clerk Trace ID: 0a6219171a2a41f6758823ff34ca2436
Screenshots
Steps to reproduce
Steps to Reproduce
- Attempt to log in via Google OAuth on Badget.io.
Browsers
Chrome
Additional context (Is this in dev or production?)
production
Thanks for this @jacksonkasi1 - Going to look into it.
I'm curious if/how this issue was resolved because I'm running into a similar issue for an Electron desktop app that wraps an existing web app.
The existing web app has been working in production. I have implemented custom protocol routing to an internal server via HTTP, and updated allowed_origins. I can authenticate to Clerk (environment and client endpoints return 200), but after Google SSO the oauth_callback has the same behavior as OP.
In staging environment, it works. In production environment, it doesn't. Is this due to some differences between the environments? The configuration is very similar, but maybe there's stricter security policies in production preventing the Electron app from working?
@encryptedcommerce take a look at this repo we created to show how we did it with electron and clerk :) https://github.com/gameglass/clerk-electron-login/
@mboudreau ... Can you help with setting these env variables mentioned in your repo : https://github.com/gameglass/clerk-electron-login/
This is what are are using, consider that xyz is our org name.
VITE_CLERK_PUBLIC_KEY="pk_xxx"
VITE_CLERK_DOMAIN=clerk.xyz.ai
VITE_HTTPS_DOMAIN=https://local.hub.electron.vite
VITE_APP_DOMAIN=https://xyz.ai
VITE_DOMAIN=http://localhost:5173
VITE_CLERK_DEV_DOMAIN=guiding-mosquito-xx.clerk.accounts.dev
We are able to run the repo but authentication with google still does not work. Can you guide ?
Please note that : https://local.hub.electron.vite/sso-callback has been added as redirect URL using clerk's API.
This is error we receive :
{"errors": ["message": "Unauthorized request", "long_message":"You are not authorized to perform this
request", "code" :"authorization_invalid"}],"clerk_trace_id"="xxxx"}
Essentially, oauth_callback always fails.
@UtsavChokshiCNU It's important to use the custom clerk provider with the custom clerk instance to inject _is_native=1 in the query string to do the native flow. It's also required to intecept the web data to remove the origin mentioned here: https://github.com/GameGlass/clerk-electron-login/blob/main/src/main/index.ts#L136
The way we're doing it is nothing special. It is literally just taking what Clerk has done for Expo/React Native and porting it to electron. The code we based it on is this: https://github.com/clerk/javascript/blob/2659108ed55d558c656d184d4113873b28e86441/packages/expo/src/hooks/useOAuth.ts#L36
However, we did find another way of doing this is a much more centralized way. You could use a website (if you have one) to go through the oauth flow, and after the flow is done, take the userid and create a Sign In Token and then use that to deeplink back to your electron application (ex: myapp://some-domain/sso-token?signInToken=<insert token here> which your app then uses this sign in token to login.
Best of luck getting it working. Cheers.
@mboudreau ... Sorry to bother you again. We were able to implement the following flow :
However, we did find another way of doing this is a much more centralized way. You could use a website (if you have one) to go through the oauth flow, and after the flow is done, take the userid and create a [Sign In Token](https://clerk.com/docs/custom-flows/embedded-email-links) and then use that to deeplink back to your electron application (ex: myapp://some-domain/sso-token?signInToken=<insert token here> which your app then uses this sign in token to login.
Login on the Desktop App (e.g., the Electron App) worked, but it is not able to refresh the token. So, I wanted to know how you have handled that.
In particular, request to touch (e.g. https:/clerk.myapp.com/v1/client/sessions/session_id/touch?__clerk_api_version=2024-10-01&_clerk_js_version=5.45.0) and /tokens endpoints kept failing with 401 unauthorized. As soon as this fails, clerk signs us out from the app.
Here is the Sequence Diagram for your reference :
sequenceDiagram
participant User
participant Desktop as Desktop App
participant WebApp as Web Frontend
participant Backend as Python Backend
participant Clerk as Clerk Auth
Desktop->>Desktop: 1. Register myapp:// protocol
User->>Desktop: 2. Launch desktop app
User->>Desktop: 3. Click "Continue with Google"
Desktop->>WebApp: 4. Open /desktop-auth
WebApp->>Clerk: 5. Check session status
Clerk->>WebApp: 6. No session found
WebApp->>Clerk: 7. Start Google OAuth flow
Clerk->>User: 8. Show Google sign-in popup
User->>Clerk: 9. Complete Google sign-in
Clerk->>WebApp: 10. OAuth Success
WebApp->>WebApp: 11. Redirect to /desktop-auth-session-generator
WebApp->>Backend: 12. Request sign-in token
Backend->>WebApp: 13. Return token
WebApp->>Desktop: 14. Redirect myapp://auth?signin-token=xyz
Desktop->>Desktop: 15. Create session with token
Note over Desktop,Clerk: Session Token Refresh Flow (Continuous)
loop Every 50 seconds
Desktop->>Clerk: Request new session token
Clerk->>Desktop: Return fresh token (60s validity)
end
Please note that our electron app's main process starts the express server (on localhost:3000) to render UI. All clerk request originates from that express server.
So I believe , production instance of clerk (clerk.myapp.com) does not allow refreshing token from localhost:3000. I want to know how you have mitigated that ?
Here are things we already tried (and failed):
- Add
localhost:3000as allowed origins on clerk instance - Update request and response headers for origin and referrer to use webapp URL rather than localhost:3000.
Your guidance is much appreciated !
@UtsavChokshiCNU Hey mate,
We actually didn't implement this flow for our desktop app yet, we're using the example at the github repo given for the time being as it's working and haven't tried this flow yet other than with our mobile app.
That being said, you should look at our web request interceptors example for clerk APIs in this file. The thing about Clerk is that authentication is done one of 2 ways: with cookies based on origin headers (browser based) or using the Authorization header and giving it the user JWT (native). The latter must have the origin header removed for it to work - you can't have both authorization and origin headers at the same time. Secondly, you'll also need to intercept the response headers so you can add the CORS headers necessary to inject your localhost domain that goes to the electron "browser" window so that V8 doesn't kick up a fuss.
And that should do it :)
For any other support requests, please contact clerk directly - they're really responsive, especially on slack.