0

I am using Fetch API in my React Native project. I do HTTP POST request to a server, which expects username and password. If login is succesfull, the server sets session cookie in Login page and then redirects to another web page called Blog. Fetch API receives the response from Blog, which has no session cookie. So I need to catch the redirect and store the session cookie before the redirect happens.

In documentation it says that redirect: 'manual' should do the job. However, I still get the response from the very last page. Redirect is not seen by Fetch API - response.redirected returns undefined. But the url of the request and response are different. What could potentially be wrong?

const url = 'url of a website ( cannot show it to you )';
// login request
const login = (profileName, password) => {
  const details = {
    benutzername: profileName,
    passwort: password,
  };

  const formBody = Object.keys(details)
    .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(details[key])}`)
    .join('&');

  console.log(`formBody to be sent: ${formBody}`);

  fetch(url, {
    method: 'POST',
    headers: {
      Accept:
        'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: formBody,
    redirect: 'manual',
  })
    .then((response) => {
      console.log('! response type !');
      console.log(response.type);
      console.log('! is redirected !');
      console.log(response.redirected);
      console.log('! response console log !');
      console.log(response.url);
      console.log('! response status console log !');
      console.log(response.status);
      return response.headers;
    })
    .then((headers) => {
      console.log('! headers for each !');
      headers.forEach((value, key) => {
        console.log(`${key} ==> ${value}`);
      });
      return headers;
    })
    .catch((error) => console.log(`error: ${error}`));
};

export { login };

Here are screenshots of Network Activity in browser:

Login: Login page network activity

Blog: Blog page network activity

Here are the logs:

LOG  ! response type !
 LOG  default
 LOG  ! is redirected !
 LOG  undefined
 LOG  ! response console log !
 LOG  https://.../Blog.xhtml?faces-redirect=true&dswid=-8890
 LOG  ! response status console log !
 LOG  200
 LOG  ! headers for each !
 LOG  cache-control ==> no-cache, no-store, must-revalidate
 LOG  content-encoding ==> gzip
 LOG  content-type ==> text/html;charset=UTF-8
 LOG  date ==> Sun, 23 Jul 2023 14:54:59 GMT
 LOG  expires ==> 0
 LOG  pragma ==> no-cache
 LOG  server ==> Apache
 LOG  set-cookie ==> dsrwid--8890=-8890; path=/; secure; Max-Age=60; Expires=Sun, 23-Jul-2023 14:55:59 GMT; SameSite=None
 LOG  vary ==> Accept-Encoding
  • First thing I would check is the Network Activity in the browser tools. See if it is what you expect in terms of responses. – Tony B Jul 23 '23 at 15:05
  • @TonyB I have uploaded the screenshots of Login and Blog pages network activity ( at very bottom of the post ). As you can see, in Login there is 302 response -> redirect. There the session cookie is stored in Set-Cookie with ID = 12qD...... Then after a few redirects, it reaches Blog with 200 response and Set-Cookie contains no ID = 12qD... –  Jul 23 '23 at 15:22
  • I think this is what you are running into... https://stackoverflow.com/questions/42716082/fetch-api-whats-the-use-of-redirect-manual – Tony B Jul 24 '23 at 03:26

2 Answers2

1

Currently manual redirects does not work with the fetch api on react-native (see here)

PhantomSpooks
  • 2,877
  • 2
  • 8
  • 13
  • 1
    Thanks for pointing out the issue with manual not working with React Native. However, I think the rest of the response is not quite related to my question. The question is not how to redirect manually, but how to catch the redirect, so that I can get the header of the first page ( Login ). With your approach I will still get the response with Blog page, which contains no cookie. –  Jul 23 '23 at 16:33
  • Im sorry. I guess I dont really understand catching redirecting. Have you tried using axios? – PhantomSpooks Jul 23 '23 at 16:56
  • I am also not great in networking, but to my understanding the issue I am having is: I send HTTP request to Login page, but server answers " you are logged in, here is your session cookie. Now you should go to Blog page ". I want to say " no thanks, I just need this first response " and grab the session cookie from the response. But Fetch API jumps in and answers to the server without my allowance " sure, I will follow " and then the server responds again " you followed successfully to Blog ". And then it " overrides " the first response from Login which has session cookie :\ –  Jul 23 '23 at 17:30
  • Regarding Axios. Yes, I tried and seems like it does the same thing. In the documentation it says, that I can use maxRedirects: 0 to not follow redirections. However, this does not work for React Native. There are many issues on github pointing out this problem, and also in the original axios docs there is a comment // `maxRedirects` defines the maximum number of redirects to follow in node.js. But I am in RN, not node :c. –  Jul 23 '23 at 17:33
  • I have a feeling that the only solution is to make a proper end-point on the server side, which will not redirect me anywhere and give simple response with session cookie. –  Jul 23 '23 at 17:36
  • I have marked your question as accepted as the first part of your answer has directly answered why redirect does not work in React Native in fetch API. The rest of your answer I consider as extra info :). Thanks! –  Jul 24 '23 at 12:24
  • I've removed it – PhantomSpooks Jul 24 '23 at 12:52
-1

Instead of using the manual, try using error

Because using redirected to manually filter out redirects can allow forgery of redirects, you should instead set the redirect mode to "error" in the init parameter when calling fetch()

Refference : https://developer.mozilla.org/en-US/docs/Web/API/Response/redirected#disallowing_redirects

  • Tried this, same result. Does not enter .catch block, just executes normally. –  Jul 23 '23 at 16:14