RSA algorithim for /auth/exchange-code
I need to authenticate users on chrome extenstion using goolge Auth. However I facing issue with ID_token retrieved by google. When I try to exchange that with endpoint we have /auth/exchange-code it give invalid algorithim. Seems opensaas or weblang only supports HS256 , not RS256 based token. Anyone suggestion to overcome ?
17 Replies
Hi @p4j4r5. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Hmm, I don't know enough to give you a confident answer yet. The knowledge sources provided do not contain information about using RSA algorithm for authentication with Wasp or handling Google Auth ID tokens.
However, in the context of Wasp, there is a discussion about generating JWT tokens and using them for authentication. This involves creating a custom API endpoint and storing the JWT tokens in local storage. The JWT token is then sent in the headers with each request to the custom API for authentication. This process is described in the Discord support thread: Best Practices for Implementing Auth System in Chrome Extension Connected to OpenSaaS (https://discord.com/channels/686873244791210014/1223328118278983680).
For more specific information about using RSA algorithm with Wasp or handling Google Auth ID tokens, I would recommend checking the official Wasp documentation or reaching out to the Wasp community for further assistance.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @p4j4r5, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
Took a look at the link that is posted above. The conversations are mainly on username/password login, not using google oauth. I would like to use google oauth with chrome extension.
I manage to get the ID_token from google oauth and using that ID_Token, i would like to exchange it to bearer JWT token so that same user is represented whether logged in from extenstion or from webpage.
the ID_token provided by google is a RSA algorithm based token and the wasp-lang seems to only support HMAC algorithim.
Could you walk me step by step how are you using the
/auth/exchange-code
endpoint?
It's not related to the OAuth token exchange, but rather it's used for exchanging our internal one-time tokens for session IDs.Idea is that a user can login via chrome extenstion or via the portal ( which is setup using opensaas). I am planning to use google oauth in this case.
I have setup Oauth credentials in google cloud console as web application and then it has both redirects authorized ( server one - development and chrome extension one). So in essence same Oauth client ID works for both.
On server I am able to login without any issues. On chrome, I manage to get to point where I recieve Oauth ID_token . It is a valid jwt token with hash algorithm RS256 instead. I was hoping to exchange that token to create session on backend and then allow user to make calls to api via extension.
Wohooo @p4j4r5, you just became a Waspeteer level 1!
const handleLogin = () => {
try {
const authUrl = new URL("https://accounts.google.com/o/oauth2/v2/auth")
const clientId = "<from oauth settings>"
const redirectUri = chrome.identity.getRedirectURL()
const state = Math.random().toString(36).substring(7)
const scopes = "profile email"
authUrl.searchParams.set("state", state)
authUrl.searchParams.set("client_id", clientId)
authUrl.searchParams.set("redirect_uri", redirectUri)
authUrl.searchParams.set("scope", scopes)
authUrl.searchParams.set("response_type", "code token id_token")
authUrl.searchParams.set("access_type", "offline")
authUrl.searchParams.set("include_granted_scopes", "true")
authUrl.searchParams.set("prompt", "consent")
authUrl.searchParams.set("nonce", "1")
chrome.identity.launchWebAuthFlow(
{
url: authUrl.href,
interactive: true,
},
async (redirectUrl) => {
if (chrome.runtime.lastError || !redirectUrl) {
return new Error(
WebAuthFlow failed: ${chrome.runtime.lastError.message},
)
}
console.log(redirectUrl, "redirectUrl")
const params = new URLSearchParams(redirectUrl.split("?")[1])
const code = params.get("code")
if (!code) {
return new Error("No code found")
}
},
)
} catch (error) {
throw new Error(
Sign-in failed: ${error.message})
}
};
The above code is an example of handler for login button on chrome extension. Using chrome.identity.launchWebAuthFlow
allows me use same Oauth credential app for both extension and portalWe expose the Google OAuth client via
wasp/server/auth
, check the example of using it here: https://wasp-lang.dev/docs/auth/auth-hooks#refreshing-the-oauth-access-token
This is the Arctic's OAuth client which you can use like this: https://arctic.js.org/providers/google
I'm not sure you can use the id_token
to then authenticate on the server, but this what we expose to you π It seems to me that id_token
is used in a different OAuth flow type then what we do in Wasp.
Maybe you can develop a flow where a logged in user in the browser gets a code that they can use to connect their account to the extension? Smth like that could be super simple πAuth Hooks | Wasp
Auth hooks allow you to "hook into" the auth process at various stages and run your custom code. For example, if you want to forbid certain emails from signing up, or if you wish to send a welcome email to the user after they sign up, auth hooks are the way to go.
I am not able to figure out the code for user creation within the wasp. When a user is created, its is updated in four places from what I see.
- user table with user ID and user email
- auth table with ID and user ID from user table.
- auth identity table capturing what is the authentication provider ( google here ) and then corresponding auth id from auth table
- session id with expiry and auth id
I primarily want session id in exchange to ID_token I received from google on extension. I see the existing /auth/exchange-code is for exchanging internal one time tokens and will not work for ID Token returned by google.
To work around this, I may need to create new endpoint that
- takes in the google ID_token, validates it against google email against the email, aud, etc.
- on successful validation, check if there is user already exist . if existing user, create a new JWT token with authID from userid and expiry .
- using this token then use the /auth/exchange-code token to get a session ID.
This work around may only work for existing users. For new users, when they fail the check , I might need to reroute them to portal to create user.
The steps you described sound good to me (if you want to have Google auth twice):
1. You need to somehow connect your user from the Chrome extension with the user in your app's DB
2. With the info you have in the Chrome ext, send a request to a custom API endpoint which can then ideally give you some session ID
3. You can try hacking the
/auth/exchange-code
or use the tokenStore
in your own endpoint or use createSession
in your own endpoint, check this code: https://gist.github.com/infomiho/3c63de7d53aba59d6293bcb59501a029#file-src-auth-ts
For new users, they'd ideally be redirect to your app and register there.
One thing I said before:
Maybe you can develop a flow where a logged in user in the browser gets a code that they can use to connect their account to the extension? Smth like that could be super simple π1. Users only register and log in, in the app 2. In their profile they have some random code 3. They enter the random code in the Chrome ext which then exchanges that code for a session ID
Gist
Implementing custom OAuth provider with Wasp 0.14.1+ (Spotify in th...
Implementing custom OAuth provider with Wasp 0.14.1+ (Spotify in this case) - .env.server
Thanks a lot.. I will give it try using what is been doinf for spotify custom OAuth.
Managed to create an API endpoint that takes in google oauth code from client and validate the user by fetching access token and user profile info from google api's. Eventually return the onetime token.
@miho Thanks a lot for sharing the reference code.
Nice! I'm glad it worked out π If you can ... share bit of that code here so the others in the community maybe get ideas or their own!
Sure will share the code soon.
Wohooo @p4j4r5, you just became a Waspeteer level 2!
@miho Here is the E2E code . Had a challenge with redirection from google to chrom extension as the extension popup doesn't stay on when Oauth flow is triggered. Workaround was to intiatiate the launchWebFlow from background script instead
https://gist.github.com/yashomi-t3h/79f738a1006b4b8b0d73dd354471f83e
Gist
Authenticating on chrome extension with OpenSaas/wasp-lang backend
Authenticating on chrome extension with OpenSaas/wasp-lang backend - background.js
Thanks a lot for sharing the this gist that involved custom Oauth provider. It gave me more insight on the methods we have within the framework to search/create user
@p4j4r5 thank you for choosing Wasp π I know it can be incomplete / confusing at times, but I like it when we figure out something together.
Do you think there is something we should add to Wasp to make your life easier? With this issue in mind?
Not sure if it is documentation or something that could help to add custom Provider might help.