Best way of handling custom oauth call Frontend to Backend?

I am looking to allow users to connect their TikTok account. My current plan is to call a webhook from the frontend, where I would process the request and feed the response back, but what's the best way of doing it? It is a standard OAuth call.
17 Replies
kapa.ai
kapa.ai2w ago
Hi @CamBlackwood. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To handle a custom OAuth call from the frontend to the backend in Wasp for connecting a TikTok account, you can use a combination of custom API endpoints and actions. Here's a recommended approach: 1. Create a custom API endpoint: You can define a custom API route in Wasp to handle the OAuth callback. This can be done using the api declaration in your main.wasp file Custom HTTP API Endpoints (https://wasp-lang.dev/docs/advanced/apis#using-the-api-externally). 2. Implement the OAuth logic: In your backend code, implement the OAuth flow logic for TikTok. This would typically involve exchanging the authorization code for an access token. 3. Create a custom action: Define a custom action in Wasp to initiate the OAuth process from the frontend. This action can be used to start the OAuth flow and handle the response Custom Signup Action (https://wasp-lang.dev/docs/auth/username-and-pass#2-creating-your-custom-sign-up-action). 4. Use the API from the client: In your frontend code, you can use the Wasp-provided API wrapper to call your custom endpoints and actions Using the API from the Client (https://wasp-lang.dev/docs/advanced/apis#using-the-api-from-the-client). Here's a basic example of how you might structure this:
// In main.wasp
api tiktokCallback {
fn: import { handleTikTokCallback } from "@src/auth/tiktok.js",
httpRoute: (GET, "/auth/tiktok/callback")
}

action initiateTikTokAuth {
fn: import { initiateTikTokAuth } from "@src/auth/tiktok.js",
}

// In src/auth/tiktok.js
export const handleTikTokCallback = async (req, res, context) => {
// Handle the OAuth callback from TikTok
// Exchange authorization code for access token
// Save the token to the user's account
}
export const initiateTikTokAuth = async (args, context) => {
// Initiate the TikTok OAuth flow
// Return the authorization URL
}

// In your React component
import { useAction } from 'wasp/client/operations';

const TikTokConnectButton = () => {
const initiateTikTokAuthFn = useAction(initiateTikTokAuth);

const handleConnect = async () => {
const authUrl = await initiateTikTokAuthFn();
window.location.href = authUrl;
};

return <button onClick={handleConnect}>Connect TikTok</button>;
};
// In main.wasp
api tiktokCallback {
fn: import { handleTikTokCallback } from "@src/auth/tiktok.js",
httpRoute: (GET, "/auth/tiktok/callback")
}

action initiateTikTokAuth {
fn: import { initiateTikTokAuth } from "@src/auth/tiktok.js",
}

// In src/auth/tiktok.js
export const handleTikTokCallback = async (req, res, context) => {
// Handle the OAuth callback from TikTok
// Exchange authorization code for access token
// Save the token to the user's account
}
export const initiateTikTokAuth = async (args, context) => {
// Initiate the TikTok OAuth flow
// Return the authorization URL
}

// In your React component
import { useAction } from 'wasp/client/operations';

const TikTokConnectButton = () => {
const initiateTikTokAuthFn = useAction(initiateTikTokAuth);

const handleConnect = async () => {
const authUrl = await initiateTikTokAuthFn();
window.location.href = authUrl;
};

return <button onClick={handleConnect}>Connect TikTok</button>;
};
This approach allows you to handle the OAuth flow securely, with the sensitive parts (like exchanging the authorization code for an access token) happening on the backend. The frontend is only responsible for initiating the flow and redirecting the user to the TikTok authorization page. Remember to handle error cases and implement proper security measures, such as using state parameters to prevent CSRF attacks in your OAuth flow. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @CamBlackwood, 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?
CamBlackwood
CamBlackwoodOP2w ago
thanks @kapa.ai - so I need to call the action from the frontend, which in turn will call the api?
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Yes, that's correct. In Wasp, the recommended approach for handling custom OAuth flows like connecting a TikTok account involves using both actions and API endpoints. Here's a breakdown of the flow: 1. From the frontend, you call an action. This action is defined in your Wasp file and implemented in your backend code. For example:
// In main.wasp
action initiateTikTokAuth {
fn: import { initiateTikTokAuth } from "@src/auth/tiktok.js",
}
// In main.wasp
action initiateTikTokAuth {
fn: import { initiateTikTokAuth } from "@src/auth/tiktok.js",
}
2. The action (initiateTikTokAuth in this case) is responsible for initiating the OAuth process. It might generate the necessary parameters for the OAuth flow and return the authorization URL Custom Signup Action (https://wasp-lang.dev/docs/auth/username-and-pass#2-creating-your-custom-sign-up-action). 3. Your frontend then uses this URL to redirect the user to TikTok's authorization page. 4. After the user authorizes your app on TikTok, TikTok will redirect back to your application, specifically to the callback URL you've specified. 5. This callback URL should correspond to a custom API endpoint you've defined in Wasp:
// In main.wasp
api tiktokCallback {
fn: import { handleTikTokCallback } from "@src/auth/tiktok.js",
httpRoute: (GET, "/auth/tiktok/callback")
}
// In main.wasp
api tiktokCallback {
fn: import { handleTikTokCallback } from "@src/auth/tiktok.js",
httpRoute: (GET, "/auth/tiktok/callback")
}
6. This API endpoint (handleTikTokCallback) will handle the OAuth callback, exchanging the authorization code for an access token and saving the necessary information Custom HTTP API Endpoints (https://wasp-lang.dev/docs/advanced/apis#using-the-api-externally). So, in summary, you're correct: you call an action from the frontend, which initiates the OAuth flow. The API endpoint comes into play later, when handling the callback from TikTok. This separation allows you to keep the OAuth initiation logic (action) separate from the callback handling logic (API endpoint), which is a clean and secure way to implement OAuth flows in Wasp. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @CamBlackwood, 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?
martinsos
martinsos2w ago
@CamBlackwood ok so you want them to connect their tik tok account -> In a way that is like authenticating with it. Although, do you want to have it enabled as an auth method also, or just use it this way, to connect and that is it? I guess connecting comes first, and if it could also be used for auth, why not right? @miho what do you think about this? I guess the first question is how can @CamBlackwood go about enabling tusers to connect with tik tok. Second is this concept of allowing them to connect with oauth account -> how does that fit with authentiaction? Is that the same thing really? If someobdy wants to do that, can we allow them to use our existing auth logic if we have it already for that oauth provider (I believe we should)? Two things in one here I guess but interesting.
CamBlackwood
CamBlackwoodOP2w ago
Hey @martinsos 🙂 so the idea is that I want them to connect it when they are already signed up to validate that they are the account they claim to be, to prevent fraud They’ll already be signed up
martinsos
martinsos2w ago
Right but they will be signed up with something else, right? They will authenticate with google, or username and pass, or something like that/
CamBlackwood
CamBlackwoodOP2w ago
exactly yeah 🙂 so the flow is, they've already signed up, but they must verify that they are the owner of an account. So my thinking atm is Client => Action => Webhook => Res => Redirect to success page. How does that sound? or can I skip webhook?
martinsos
martinsos2w ago
You basicaly need them to authenticate again, but with tik tok, and not for the Wasp login purposes, but for the purposes of showing that it is indeed their account. I will let @miho answer this one since he is the auth expert!
CamBlackwood
CamBlackwoodOP2w ago
Yes exactly 🙂 Thanks! @martinsos just reading this back again- does that mean I need to reinvoke wasp auth? cc @miho
miho
miho2w ago
I'd refer you to my custom Spotify auth impl. https://gist.github.com/infomiho/3c63de7d53aba59d6293bcb59501a029 1. We have one custom API endpoint to create a "redirect" (client -> goes to custom API endpoint -> redirects to Spotify) 2. We have a custom API endpoint to handle the Spotify callback - this is where you would get the Tik Tok details. This is where you can save them. You don't need to create users / make it a real Wasp auth - but just save what you receive in the TikTok response on the context.user you get in the custom API endpoint 🙂
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
CamBlackwood
CamBlackwoodOP2w ago
that looks perfect, thanks so much 🙏
miho
miho2w ago
To answer @martinsos
Second is this concept of allowing them to connect with oauth account -> how does that fit with authentiaction? Is that the same thing really? If someobdy wants to do that, can we allow them to use our existing auth logic if we have it already for that oauth provider (I believe we should)? Two things in one here I guess but interesting.
I guess you are asking if we can expose OAuth flow to be used outside of our auth flow. Supporting both things will make us maintain both flows in our codebase which is not bad by itself if it's worth it. I'm not sure how useful it is to have bespoke support for this in the framework. Take a look at the Spotify gist I linked, it's using arctic and defining two custom API endpoints - there is really minimal amount of code. I guess, what I'm saying, I'm not sure supporting this in the framework is that much of a benefit for the users 🤷‍♂️
CamBlackwood
CamBlackwoodOP2w ago
Just to update - I’ve given it a bit of a crack so far; unfortunately TikTok is not supported by arctic so I’m going to try and work around it, I don’t see why it isn’t possible
miho
miho2w ago
You could maybe try using their generic OAuth 2.0 client? https://arcticjs.dev/guides/generic-oauth2-client
Arctic
Generic OAuth 2.0 client
Arctic is a collection of OAuth 2.0 clients for popular providers.
miho
miho2w ago
Also, I've read somewhere their OAuth impl isn't following the standard 🤦‍♂️ I think code like this might be useful for you: https://github.com/AudiusProject/audius-protocol/blob/8c4ea49b16af33b88eb061b1c6f6d6fb2c32083e/packages/identity-service/src/routes/tiktok.js#L21 (It's a random piece of code from the internet, but it should work by the looks of it)
GitHub
audius-protocol/packages/identity-service/src/routes/tiktok.js at 8...
The Audius Protocol - Freedom to share, monetize, and listen to any audio content. - AudiusProject/audius-protocol
CamBlackwood
CamBlackwoodOP2w ago
Thanks Miho, I'll give this a look
martinsos
martinsos2w ago
@miho got it -> you are saying it is so simple to implement it outside of auth flow, that it is not worth it supporting it by us, potentially. Still, as a user, it feels a bit like aaaah, Wasp has it, why I have to implement it again :D. But ok, we are aware of it, we can let it be, see if there will be more demand in the future.
Want results from more Discord servers?
Add your server