Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Oauth. Where should use be redirected to after authenticating with the third party?

This is my first time implementing OAuth, so I'm just trying to wrap my head around the whole flow.

I'm trying to implement OAuth for Stripe Connect. So in step 4 you're sending a POST request with your client secret to the Stripe servers, which I assume means your back end will be handling that.

Want to make sure I'm thinking about this correctly. After the user authenticates with Stripe, they'll be redirected to a link you've provided (with the Auth Code as a param). Are you suppose to redirect back to the front end client and then the front end client sends that Auth Code to your server, which would then send that and the client secret to Stripe? Or would you redirect to some route on your backend which would then take the Auth Code and redirect the user again to the front end client (one less network request)?

edit: Looking at this example. So it seems like the user will actually make a GET request to your server which will redirect them to Stripe and then make another GET request to another route on your server after authenticating.

edit 2: After some more digging this is what I think I'm going to do:

  1. User clicks "Connect To Stipe" and the front end client sends a GET request to my server.
  2. My server uses uuid/v4 to generate a random string and base64 encodes it.
  3. The unencoded string is saved to my database and the encoded string is appended as a state parameter.
  4. My server redirects the User to Stripe's Oauth link with the encoded state as a param.
  5. User authorizes with Stripe and is redirected to a loading page on my front end.
  6. Front end client sends a POST request to my server with the Auth Code from Stripe and the state.
  7. My server decodes the state and checks it with the state in the database.
  8. If the states match, my server sends a POST request to Stripe with the Auth Code and the Client Secret.
  9. Stripe sends my server a the User's Account Id, which is then stored in their User model of my database.

edit 3: After having implemented a couple integrations, I'd like to give another update for this question from a couple years ago.

I would create a state parameter as a uuid, but not encode it. There's no point. I would also store the state parameter in redis/dynamodb and add a ttl expiration parameter of 1min-10min. So the state parameter would be the key and I'd include the userId or tenantId as a value. When the user gets redirected back to my server, I'll fetch the state parameter from my key/value store. If it doesn't exist (or expired), I'd return a 400. Otherwise, I'd continue with the OAuth process.

like image 889
BryceLarkin Avatar asked Oct 24 '25 05:10

BryceLarkin


2 Answers

Personally I'd redirect them to a front-end page that sends the authorization code to my backend server so I could render a loading animation while I finish the user's delegated authorization process. That way the user knows what's going on and isn't left hanging on a slow identity/authorization server. Either way is fine though, and the redirect to a route on the 'backend' (one without a frontend view is what I think you mean) that will eventually redirect the user to a route with a frontend view (dependent on whether the authorization resulted in a success or failure) would be fine too.

like image 76
Randy Avatar answered Oct 26 '25 17:10

Randy


If I understand this correctly, the redirect link should points to your backend server. Then this redirect route on your backend server makes request to the Stripe's endpoint on Step 4.

In many cases, the access token and refresh token are stored in the database for future requests for this user. These tokens are very sensitive information that can be used to make Stripe transactions, so it's best not to expose them in the frontend.

I got really confused with OAuth stuff in the beginning, too.

Response to the questioner's edit#2:

On #2, I'm not sure if there is a need to hit your server before sending the initial request to Stripe. It's quite common for these 'sign up via ..' buttons to have direct link to the service. So, there could be <a> button that has something like href="https://connect.stripe.com/express/oauth/authorize?redirect_uri={URL}&client_id={ID}&state={STATE_VALUE}". The STATE_VALUE can be generated when the user access the page.

Then when the user clicks the button, the user is navigated to Stripe's signup/login page. When the user finishes filling out the form, Stripe takes the user to the 'redirect_uri'. Here (#5), I am not quite sure what you mean by 'User is redirected to a loading page on my frond end'. I'm thinking, it's a url to your application, so this request has to hit your server. The page the user just came from cannot receive and handle the response unless the request was made by ajax. In the case of Stripe, it looks like their flow is designed for simple html requests. (Some services might do this via ajax, in which case there is response-handling in front end code.)

So, it's your server that receives the auth code from Stripe. The server checks the STATE_VALUE, makes POST request to Stripe with the auth code, receives secret/refresh keys from Stripe. Then, the server can respond to the user with whatever page that's appropriate.

I guess you could have your server respond right away before making the last POST request, and have the front end code do it via ajax and show the loading page while making the request. However, I disagree that that's a good option; it can expose sensitive info, and the loading time isn't long enough to be be a bad UX, in my opinion.

So from the browser's perspective,

When the user clicked a link to Stripe login

-> makes a request to Stripe's auth page

-> receives a page containing a form from Stripe

When the user submits the Stripe form

-> makes a request to Stripe to submit the form

-> receives 302 from Stripe, redirecting to your app's redirect url (containing auth code)

-> makes request to your server

-> receives a new page from your server

Feel free to comment/correct.

like image 27
Hiro Avatar answered Oct 26 '25 19:10

Hiro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!