Coder Social home page Coder Social logo

Comments (22)

bhubr avatar bhubr commented on August 15, 2024 1

OK I kind of see,

I need to see some digging: the isCrossOrigin stuff had been added by a contributor which had this specific use case.

I had started a big overhaul of the docs but never got through it, and I definitely should get back to it.

But first, I'm gonna try and retrieve the code samples I think I have somewhere. I have some time right now so I'm gonna get right to it. Stay tuned, I'll keep you posted!

from react-simple-oauth2-login.

Djalalov avatar Djalalov commented on August 15, 2024 1

OK I made it work. I'll show you an excerpt adapted from the example in example/server (it's Node.js code but I'll comment it).

It's a bit specific to GitHub but I guess you don't have to worry about it, since your screenshot suggests that you already got the access token part right!

To summarize:

1. You get back the `code` from Jira,

2. You send the code to Jira with other params (secrets etc.), and it responds with an access token

3. You wrap your final response to the client in a script that will send a message to the "parent" window of the popup, that will include the data you got back from Jira.

4. That data will be passed to the `onSuccess` callback of the React component.

It is crucial that you set isCrossOrigin on the component, but you already got that part right too, don't you 😉 ?

Last thing: here I had to JSON-encode the parsed data that I got from GitHub. But seeing that you get JSON data back from Jira, I guess you can inject it in the script "as is", in lieu of ${JSON.stringify(data)}.

Let me know if that helped!

// Endpoint that handles the `/callback` URL
app.get('/callback', async (req, res) => {
  // Get the `code` parameter from the query string
  const { code } = req.query;
  // Those are parameters that I got from environment variables
  const { tokenUrl, clientId, clientSecret, redirectUri } = oauth;
  // GitHub wants everything in an url-encoded body
  const payload = qs.stringify({
    code,
    client_id: clientId,
    client_secret: clientSecret,
    redirect_uri: redirectUri,
    grant_type: 'authorization_code',
  });
  try {
    // Send the token request to GitHub (details may vary for other providers)
    const resp = await axios.post(tokenUrl, payload, {
      headers: {
        'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
      },
    });
    // Since GitHub gives as back the result in url-encoded form, we need to parse it
    const data = qs.parse(resp.data);

    // **************************************************************************
    // 👇👇👇 The interesting part: sending the result back to the client 👇👇👇
    // **************************************************************************
    res.send(`<script>
      window.addEventListener("message", function (event) {
        if (event.data.message === "requestResult") {
          event.source.postMessage({"message": "deliverResult", result: ${JSON.stringify(
            data
          )} }, "*");
        }
      });
    </script>`);
  } catch (err) {
    console.error('Error while requesting a token', err.response.data);
    res.status(500).json({
      error: err.message,
    });
  }
});

Oh thanks a lot. Let me try.

from react-simple-oauth2-login.

Djalalov avatar Djalalov commented on August 15, 2024 1

@Djalalov Did you eventually succeed?

Hi @bhubr, yes.

After several attempts, we have just achieved desired result.

image

Just for the reference: This snippet is the key. Just because after Jira redirect user to the endpoint 8080/callback with code and state, backend was literally catching that response from Jira, exchanging code and state to access_token and not doing anything else. You snippet of code was actually the code we needed to send the data to the front.

I really appreaciate your help. Thanks

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

Hello Andrea!

Just to let you know: the isCrossOrigin flag is a rather recent addition.
It was added by a contributor who had a different setup and workflow than mine.

I'd need to know:

  • what's your server stack, on which port it runs, if CORS is properly configured
  • on the client side, what precise error message you get (it can be screenshots of your network tools). I don't really understand the "href" part in this: error in console about not being able to read the href.

Cheers

from react-simple-oauth2-login.

AndreaMaestri18 avatar AndreaMaestri18 commented on August 15, 2024

I don't have any control on the server unfortunately, and no the cors are not properly configured.
Therefore I can't just set isCrossOrigin to false otherwise it will show me this error: DOMException: Permission denied to get property "href" on cross-origin object from PopupWindow line 120.

However, once i complete the login and i am redirected, the code is console.logged and no more error is there.

On the other hand, if isCrossOrigin=true i dont get the error, but im not redirected in the same browser window (i'm redirected in the popup) and the code is not console.logged even tho the unsuccess callback is the same.

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

Sorry for the delayed response.

When you say "I don't have any control on the server", you mean the server backing your React app, not the OAuth2 server?

That said, I might have a solution. The isCrossOrigin flag is supposed to be used when the redirectUri param points to an URL on the server.

You might try setting redirectUri to your React app's URL. In this case, your React app can extract the code from the URL and send it to your backend app, which then requests a token from the OAuth2 provider, then sends it back to your frontend app. But maybe you tried this already?

from react-simple-oauth2-login.

AndreaMaestri18 avatar AndreaMaestri18 commented on August 15, 2024

no i mean the Oauth2 server, I don't have control on that, so I can't set the cors in the header of the response (I'm logging in a different application than my react app). The redirectUri that i use is localhost (because I want to be redirected in my app after I log-in)

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

Ok. Sure, unless it's your own OAuth2 server & infrastructure, you can't control how it behaves regarding CORS.

The thing is, you're supposed to have your own backend app if you want to use the "authorization code" flow. This app can be on your localhost while you're developing. Then there are two cases:

  • If your redirectUri is set to your server app, you should use isCrossOrigin.
  • If it's set to your React app, you needn't use isCrossOrigin.

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

I could elaborate a little more but I'm unsure as to whether you have a backend app of your own??

from react-simple-oauth2-login.

AndreaMaestri18 avatar AndreaMaestri18 commented on August 15, 2024

I have also a backend app yes! But the problem is that if the redirectUri is my react app and I don't use the isCrossOrigin I get the error I mentioned before

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

Is your project open source? If so, I could have a look.

Otherwise I have a few possible hints:

  • is CORS configured on your backend app? If not, it's one of the possible causes of failure.
  • other than configuring CORS on your backend, you might (if you're using Create React App) set the proxy setting to your backend's URL, so that when you send an XHR request with your auth code (e.g. POST to http://localhost:3000/oauth/token) this request is seamlessly proxied to your server.
  • another way would be to do without CORS altogether, by having both your backend and frontend under the same domain. It should be possible to do so with a local webserver (e.g. Nginx or Apache running on localhost) with reverse proxies to your backend & frontend apps. If you're familiar with Docker it might even be a bit simpler to achieve.

If you need help with the last option (webserver with or without Docker), let me know what are your OS and server stack (PHP? Node? Python? other? which framework?) and I'll try to come up with the right setup instructions & config files.

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

Hi @AndreaMaestri18

Have you progressed on the issue?
Let me know if you need help!

from react-simple-oauth2-login.

Djalalov avatar Djalalov commented on August 15, 2024

Hi @bhubr,

First of all, thanks for contributing for this simple yet very useful component.
I am having the same problem as @AndreaMaestri18 faced

Here are my details:
Tech Stack =>

  1. Backend: Java
  2. Front: React
  3. Auth server: Jira

So all in all we have 3 parties involved in auth logic here and we are trying to implement the Auth Code grant flow.

We are having 2 different ports
front React: localhost:3002
back Java: localhost:8080/callback
port 8080/callback is given as redirect url and when auth is initiated from port 3002, user will be taken to the Jira server and give permissions to the app and returns to 8080/callback with accessToken which is nice

Problem:
We can not get this access token in port 3002

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

Hi @Djalalov

Thanks! I guess you had a question in mind?

from react-simple-oauth2-login.

Djalalov avatar Djalalov commented on August 15, 2024

Screenshot from 2023-11-29 14-02-45

We have the exact scenario described here but we dont understand what it means for the step 2. It says set the auth url in backend and it should return something. Can you please elaborate on this ?

from react-simple-oauth2-login.

Djalalov avatar Djalalov commented on August 15, 2024

image

Here is the screenshot
This is situtaion when we have crossOrigin = true

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

[EDIT] SOLVED! See comment below!

Might I ask you some clarification please?

When you "authorize" your OAuth app in the popup window, are you directly redirected to http://localhost:8080/callback with the access token? That's what your screenshot seems to indicate...

What I mean is, don't you first get a "code" that you then "exchange" for an access token by sending a POST request to a specific endpoint on Jira?

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

OK I made it work. I'll show you an excerpt adapted from the example in example/server (it's Node.js code but I'll comment it).

It's a bit specific to GitHub but I guess you don't have to worry about it, since your screenshot suggests that you already got the access token part right!

To summarize:

  1. You get back the code from Jira,
  2. You send the code to Jira with other params (secrets etc.), and it responds with an access token
  3. You wrap your final response to the client in a script that will send a message to the "parent" window of the popup, that will include the data you got back from Jira.
  4. That data will be passed to the onSuccess callback of the React component.

It is crucial that you set isCrossOrigin on the component, but you already got that part right too, don't you 😉 ?

Last thing: here I had to JSON-encode the parsed data that I got from GitHub. But seeing that you get JSON data back from Jira, I guess you can inject it in the script "as is", in lieu of ${JSON.stringify(data)}.

Let me know if that helped!

// Endpoint that handles the `/callback` URL
app.get('/callback', async (req, res) => {
  // Get the `code` parameter from the query string
  const { code } = req.query;
  // Those are parameters that I got from environment variables
  const { tokenUrl, clientId, clientSecret, redirectUri } = oauth;
  // GitHub wants everything in an url-encoded body
  const payload = qs.stringify({
    code,
    client_id: clientId,
    client_secret: clientSecret,
    redirect_uri: redirectUri,
    grant_type: 'authorization_code',
  });
  try {
    // Send the token request to GitHub (details may vary for other providers)
    const resp = await axios.post(tokenUrl, payload, {
      headers: {
        'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
      },
    });
    // Since GitHub gives as back the result in url-encoded form, we need to parse it
    const data = qs.parse(resp.data);

    // **************************************************************************
    // 👇👇👇 The interesting part: sending the result back to the client 👇👇👇
    // **************************************************************************
    res.send(`<script>
      window.addEventListener("message", function (event) {
        if (event.data.message === "requestResult") {
          event.source.postMessage({"message": "deliverResult", result: ${JSON.stringify(
            data
          )} }, "*");
        }
      });
    </script>`);
  } catch (err) {
    console.error('Error while requesting a token', err.response.data);
    res.status(500).json({
      error: err.message,
    });
  }
});

from react-simple-oauth2-login.

Djalalov avatar Djalalov commented on August 15, 2024

[EDIT] SOLVED! See comment below!

Might I ask you some clarification please?

When you "authorize" your OAuth app in the popup window, are you directly redirected to http://localhost:8080/callback with the access token? That's what your screenshot seems to indicate...

What I mean is, don't you first get a "code" that you then "exchange" for an access token by sending a POST request to a specific endpoint on Jira?

Yes, its where things get complicated. What you are saying is the standerd flow and this was our plan at first IDEALLY. But that didnt work since we have CORS issue. We tried move the logic of exchanging the code to token in the backend right after when Jira hits 8080/callback

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

[EDIT] SOLVED! See comment below!
Might I ask you some clarification please?
When you "authorize" your OAuth app in the popup window, are you directly redirected to http://localhost:8080/callback with the access token? That's what your screenshot seems to indicate...
What I mean is, don't you first get a "code" that you then "exchange" for an access token by sending a POST request to a specific endpoint on Jira?

Yes, its where things get complicated. What you are saying is the standerd flow and this was our plan at first IDEALLY. But that didnt work since we have CORS issue. We tried move the logic of exchanging the code to token in the backend right after when Jira hits 8080/callback

Interesting. Do you mean that you initially intend to redirect to localhost:3002/callback, then send the code to your backend, have it request the token and send it back to your React app?

I guess you already tried configuring CORS on the backend? I don't know how that would be done with Java (Spring Boot maybe?) but it's also a common issue when dealing with requests from a React app on a Node.js backend.

But then, there are ways to fix it without necessarily doing cross-origin requests:

  • One would be to use the "proxy" param in package.json - it should work if you're using Create React App, but I'm not sure if it will with other bundlers/build systems (Vite, etc.)
  • Another would be to dockerize the whole thing: backend + React app, though as I'm writing it, I'm having kind of a doubt. I know it works in production, but I'm unsure about it in development. The idea is to put both the backend and the frontend behind an nginx reverse proxy, with all backend traffic going to e.g. port 8080 (it would require to have all backend endpoints below a common prefix, e.g. /api) and all frontend traffic (everything that's not /api) going to .e.g. 3002. I think I could provide an example if needs be (that would help me make sure that it's actually doable - or not).

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

@Djalalov Did you eventually succeed?

from react-simple-oauth2-login.

bhubr avatar bhubr commented on August 15, 2024

@Djalalov Glad it helped!

from react-simple-oauth2-login.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.