Comments (22)
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.
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 Did you eventually succeed?
Hi @bhubr, yes.
After several attempts, we have just achieved desired result.
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.
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.
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.
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.
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.
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 useisCrossOrigin
. - If it's set to your React app, you needn't use
isCrossOrigin
.
from react-simple-oauth2-login.
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.
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.
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 tohttp://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.
Have you progressed on the issue?
Let me know if you need help!
from react-simple-oauth2-login.
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 =>
- Backend: Java
- Front: React
- 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.
Hi @Djalalov
Thanks! I guess you had a question in mind?
from react-simple-oauth2-login.
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.
Here is the screenshot
This is situtaion when we have crossOrigin = true
from react-simple-oauth2-login.
[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.
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:
- You get back the
code
from Jira, - You send the code to Jira with other params (secrets etc.), and it responds with an access token
- 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.
- 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.
[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.
[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 inpackage.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.
@Djalalov Did you eventually succeed?
from react-simple-oauth2-login.
@Djalalov Glad it helped!
from react-simple-oauth2-login.
Related Issues (20)
- When I added to my project ,occured problem? HOT 1
- Prop for selecting redirect strategy HOT 1
- When using code response, DOMException is silenced HOT 1
- How to specify scopes HOT 1
- Redirect URI is not encoded HOT 3
- Tests don't work anymore 😱 HOT 2
- End-to-end testing HOT 2
- How to handle browsers that don't support popup read / postMessage HOT 1
- Credit original contributors HOT 4
- Support Auth Code + PKCE flow
- Adding additional query params breaks the client id HOT 2
- Cannot resolve dependency './settings-code' at '...\example\client\src\settings-code' HOT 5
- Improve docs & examples HOT 2
- Setup semantic release for auto versioning, packaging / publishing, & changelog HOT 1
- Not working with React 17.0.2 HOT 4
- Headless functionality in hook
- Using with typescript! HOT 4
- Not working with react 18+ HOT 10
- "The popup was closed for an unexpected reason" popup is still open HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-simple-oauth2-login.