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");
  // }

};

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

12 Comments

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
CORS ERROR: Access to XMLHttpRequest at 'strava.com/oauth/…' (redirected from 'localhost:8800/api/auth/strava/callback') from origin 'localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
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?
I assume 3000 is the react port and 8800 is your node port, right?
yes, what is up with this. That is strava blocking cors inst it
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.