0

I have been looking at the other questions regarding this topic but I cannot seem to figure out the way to do it to achieve my problem.

I have been using Strava api which uses OAuth 2.0. Which follows this process

  1. Click connect button
  2. Then redirect user to data permissions page
  3. after permissions granted then this returns a one time code used to retrieve the access token then the user is redirected to a redirect_uri provided by the developer
  4. I redirect the user to another api endpoint of mine which successfully retrieves the access token

Retrieving the access token works I then set the access token as a cookie. This is how I will check user is connected to Strava.

The issue occurs here. I use window.open() to redirect after button click to my backend route which initiates OAuth 2 process. This is where my issue occurs so I want to use context hook in frontend so I tried changing to axios request instead of window.open but I get a cors error due to not having access for Strava cors

Initially I was just checking if res.cookie existed in backend then redirect them to the pages after authenticated but I want to use private routes. Since window.open doesn't return anything I cannot update and check my context to allow user access to private routes.

Does anyone have a better structure or way for me to carry out this process without window.open()

code below:

Home page:

function HomePage() {


   const stravaAuth = async (e) => {


  
  window.open("http://localhost:8800/api/auth/strava/callback", "_self");
  // const res = await axios.get("http://localhost:8800/api/auth/strava/redirect");
  // console.log("res = ", res.data);  
};
  return (
    <div className="App">
      <button onClick={stravaAuth}>Connect to strava!</button>
    </div>
  );
}


export default HomePage;

backend:

let accecssToken;
let athleteID;

async function getDataPromise() {
  const link = `https://www.strava.com/api/v3/activities?access_token=${accecssToken}`;
  console.log("Link = ", link);
  const response = await axios.get(link);
  console.log("Response = ", response.data[0]);
  return response.data;
}

export const stravaActivities = async (req, res) => {
  const data = await getDataPromise();
  console.log("data = ", data);

  return res.json(data);
};

export const stravaCallback = async (req, res) => {
  const client_id = process.env.CLIENT_ID;
  const scope = process.env.SCOPE;
  const redirect_uri = process.env.REDIRECT_URI;
  res.redirect(
    `http://www.strava.com/oauth/authorize?client_id=${client_id}&response_type=code&/exchange_token&approval_prompt=force&scope=${scope}&redirect_uri=${redirect_uri}`
  );

  const accessCode = req.code;
  console.log("One time code = ", accessCode);

  return res.status(200);
};

export const stravaRedirect = async (req, res) => {
  const url = req.url;    
  console.log("url = ", url);
  const accessCode = req.query.code;

  console.log("One time code = ", accessCode);
  const isAuthenticated = false;
  const link = `https://www.strava.com/api/v3/oauth/token?client_id={client_id}&client_secret={client_secret}&code=${accessCode}&grant_type=authorization_code`;
  try {
    const response = await axios.post(link);
    console.log("response = ", JSON.stringify(response.data));
    console.log("access token = ", response.data.access_token);
    accecssToken = response.data.access_token;
    athleteID = response.data.athlete.id;

    res.cookie("Token", accecssToken);
    return res.json(response.data);

  } catch (error) {
    console.log(error);
  }
  res.send(accecssToken);
  // if (res.cookie !== null) {
  //   res.redirect("http://localhost:3000/Activities");
  // } else {
  //   res.redirect("http://localhost:3000");
  // }

};
program.exe
  • 451
  • 4
  • 12

1 Answers1

0

You should not have any issues with cors when you working with your own server. If your react app is served on different url than your node - you can use cors library to allow that.

Anyway - does your server needs the accessToken at all? If not, you can keep it in the client cookie, no need to pass it to server and back to your client.

Usually - when using third party auth, you should be able to send some auth required request when client side app is initilized, then you can redirect your client to the private route \ login route per the response.

Do not rely on res.cookie, you should rely on response from your oAuth provider or your own server if you use it to process something with your credentials.

yeya
  • 1,968
  • 1
  • 21
  • 31
  • yes access token is required on the server as it must be included in strava api requests to endpoints for the users data with your third point yes I see what you mean after the access token is retrieved in my case the client is authenticated. So should I then redirect to that route are you able to point me to an example of this. For the cors point you make the error appears when redirecting to strava server I can provide the error message in the next comment – program.exe Nov 28 '22 at 13:03
  • CORS ERROR: Access to XMLHttpRequest at 'https://www.strava.com/oauth/authorize?client_id=client_id&response_type=code&/exchange_token&approval_prompt=force&scope=activity:read_all,activity:read&redirect_uri=http://localhost:8800/api/auth/strava/redirect' (redirected from 'http://localhost:8800/api/auth/strava/callback') from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. – program.exe Nov 28 '22 at 13:03
  • like you said redirect to the private route is the 3rd party auth provider is OK but how can I know in the frontend if that user is authenticated. All the frontend does is window.open() but how is it possible to know that user is authenticated for the future of the users session? – program.exe Nov 28 '22 at 13:08
  • I assume 3000 is the react port and 8800 is your node port, right? – yeya Nov 28 '22 at 13:39
  • yes, what is up with this. That is strava blocking cors inst it – program.exe Nov 28 '22 at 13:40
  • No, I think it is your dev server that blocks it – yeya Nov 28 '22 at 13:44
  • Check this: https://stackoverflow.com/a/64641435/3107689 – yeya Nov 28 '22 at 13:46
  • I have tried this before I even tried making just a react direct axios request to that url so no backend server involved and get still the same error what makes you think it is my server? – program.exe Nov 28 '22 at 13:49
  • Not your node server, your react dev server. The dev server should add the required headers so that the browser will not block – yeya Nov 28 '22 at 13:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/249953/discussion-between-program-exe-and-yeya). – program.exe Nov 28 '22 at 13:55
  • I sent dm in discussion chat – program.exe Nov 28 '22 at 13:56
  • are you able to check discussion again – program.exe Nov 29 '22 at 21:15