Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookie-Based Authentication Is Not Possible #19958

Closed
kevin074 opened this issue Jun 29, 2018 · 20 comments
Closed

Cookie-Based Authentication Is Not Possible #19958

kevin074 opened this issue Jun 29, 2018 · 20 comments
Labels
Ran Commands One of our bots successfully processed a command. Resolution: For Stack Overflow A question for Stack Overflow. Applying this label will cause issue to be closed. Resolution: Locked This issue was locked by the bot.

Comments

@kevin074
Copy link

kevin074 commented Jun 29, 2018

Environment

Environment:
OS: macOS High Sierra 10.13.3
Node: 8.11.1
Yarn: 1.7.0
npm: 5.6.0
Watchman: 4.9.0
Xcode: Xcode 9.2 Build version 9C40b
Android Studio: Not Found

Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: ~0.55.2 => 0.55.4

Description

Hi, I am creating an app for work with zero chance of changing our custom coded backend authentication. It is cookie based as such:
1.) getAuthCookie() --> response contains a cookie, authCookie = fsadfsfreqwrqw.
2.) submitLoginInfo() with authCookie and user info

if at step 1 the request is sent with a cookie then it won't send back a new authCookie.

So the problem is when a user has an expired cookie stored in app, it'd keep using that cookie instead and the backend won't ever allow authentication to pass. They would have to restart the app to erase all cookie storage to pass authentication.

here are the things I have tried:
1.) native fetch api via credentials:'omit' / withCredentials: false, all permutations don't work
2.) use axios and repeat my first step
3.) tried to use axios with tough-cookie + axios-cookiejar-support, both required node functions that aren't available in RN
4.) react-native-cookie by joeferraro, this method worked before CRNA came in, but now it's showing messages that requires me to open xcode and add file, this isn't possible with current CRNA build and ejecting isn't advised.
5.) hard code Cookie headers via axios and RN's Fetch. This didn't work because it adds onto the cookies already in the system instead of actually setting the header to whatever string I put in.

Number 4 that I listed is how I know that it isn't code problem on my end since it used to work when I can just clear all cookies whenever the user gets to the login page.

solutions that'd help with my problem:
1.) able to choose when NOT to pass a cookie with request (not sure if the new set-cookie response header would replace my old cookie though).
2.) manipulate cookie on my own like react-native-cookie used to allow me.
3.) able to hard set the Cookie in Fetch headers.

I have been on this issue for weeks and I have also exhausted all resources, reddit/discord/stackoverflow/google. The successful example all involved react-native-cookie, but with that option gone I believe the community has no way of doing this anymore.

@CrazyPython

This comment has been minimized.

@hramos hramos added the Resolution: For Stack Overflow A question for Stack Overflow. Applying this label will cause issue to be closed. label Jul 2, 2018
@react-native-bot react-native-bot added the Ran Commands One of our bots successfully processed a command. label Jul 2, 2018
@react-native-bot
Copy link
Collaborator

Please use Stack Overflow for this type of question.

@ghost
Copy link

ghost commented Jul 24, 2018

So does this mean cookies will not be sent automatically by fetch calls?

@kevin074
Copy link
Author

cookies should be sent automatically now, pretty sure there is an old ticket about this and the feature was added to RN quite a while ago.

I have actually finished doing this feature and described doing so in this post
https://www.reddit.com/r/reactnative/comments/8ueyy4/need_some_help_with_cookiebased_authentication/

@bucketclan
Copy link

Cookies were working fine for me until 0.55.4. Cookies stopped being sent from 0.56.

@dieterhoeven
Copy link

Having the same issue as @Themarsguy
We are using cookies for authentication (set-cookie response from PHP endpoint is set upon authentication, cookie is sent along subsequent HTTP requests to resources), but this no longer works in RN 0.56

@DiemasMichiels
Copy link

We fixed this issue by adding credentials: 'include' to the fetch calls.

await fetch(route, {method: 'GET', headers, credentials: 'include'})

@bucketclan
Copy link

bucketclan commented Aug 1, 2018

It seemed to only work if we have credentials: 'include'. Anyways, it does not seem to work for me in 0.56.
I feel #19770 might fix the issue.

@thecryptovalley
Copy link

@Themarsguy Worked for me in 0.56.
Put credentials: 'include' outside the headers.

@bucketclan
Copy link

Hmm, using outside the headers and works till 0.55.4, but does not on 0.56. Are you all using expo or react-native(without expo)?
I am using react-native.

@dieterhoeven
Copy link

dieterhoeven commented Aug 8, 2018

@Themarsguy
we are not using expo. Including the credentials seems to have fixed the issue for us, it worked before without specifying.

@alex-wgsn
Copy link

Same issues in v0.56
cookies are not sent
credentials: 'include' helps

@fangasvsass
Copy link

fangasvsass commented Sep 27, 2018

Same issues in v0.56
cookies are not sent
credentials: 'include' helps

but it can not work for Andoird ,is there a solution?

@GetSource1234
Copy link

GetSource1234 commented Sep 28, 2018

Got the same issue in RN 0.57.1. Recently, I did upgrade from 0.51.1 to 0.57.1 and spotted issue with cookie-based authentication. In RN 0.51 you would be able to use persistent cookie without any additional flags. Now (in RN 0.57), you need to use credentials: 'include' . I am wondering what was the reason to introduce explicit credentials: 'include' flag.

@ciriac
Copy link

ciriac commented Oct 2, 2018

Would have been nice if this was included in the changelog.

@kyhnlbyrk
Copy link

kyhnlbyrk commented Dec 19, 2018

hey guys,
with fetch

method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
          Cookie: cookie,
        },
        credentials: 'include',

this code is working on iOS, cookies are sent, but in Android its now working ! If I change Cookie name to something else, then its sent. However, in the server its not a valid Cookie..

@rheng001
Copy link

rheng001 commented Mar 1, 2019

@kyhnlbyrk @fangasvsass

I have the same problem with Android. Did you ever get this to work?

@kunal886496
Copy link

kunal886496 commented Mar 22, 2019

Exactly. Something better will rise soon! Bye Bye react-native.

@jerolimov
Copy link
Contributor

Hello, I had the same problem here and analysed the internal issue:

The problem is a combination of NetworkingModule.java and the usage of WritableNativeMap. The function translateHeaders maps the OKHTTP header objekt to a React Native header map. Headers with the same key was overridden because the hasKey method always return false.

private static WritableMap translateHeaders(Headers headers) {
WritableMap responseHeaders = Arguments.createMap();
for (int i = 0; i < headers.size(); i++) {
String headerName = headers.name(i);
// multiple values for the same header
if (responseHeaders.hasKey(headerName)) {
responseHeaders.putString(
headerName,
responseHeaders.getString(headerName) + ", " + headers.value(i));
} else {
responseHeaders.putString(headerName, headers.value(i));
}
}
return responseHeaders;
}

That hasKey always return false is an implementation error in ReadableNativeMap and WritableNativeMap (which extends the readable map). This native maps supports two different modes, which can be enabled and disabled for all maps with a static boolean useNativeAccessor.

This flag defines if the ReadableNativeMap reads data from a native map or a internal (java.util.) HashMap.

But the problem was that WritableNativeMap always writes into the native map and never uses the (Readable) internal HashMap.

That was the reason why hasKey always return null if useNativeAccessor was false and only one header was returned by translateHeaders.

Like said by @hey99xx in #21795 (comment) and by @Return-1 #23005 (comment) its possible to activate the this native accessor, if you add this code to your own/project MainActivity.java:

Add this imports:

import com.facebook.react.bridge.ReadableNativeArray;
import com.facebook.react.bridge.ReadableNativeMap;

And this add the beginning of the createReactActivityDelegate method, before your application was loaded.

        ReadableNativeArray.setUseNativeAccessor(true);
        ReadableNativeMap.setUseNativeAccessor(true);

For me this works fine. But notice that this global flag may cause some other troubles.

I also started to fix this behaviour in the latest React Native 0.59.3 release, but notice than that the master version of ReadableNativeMap/WritableNativeMap was already changed.

The commits b257e06 and a062b34 by FB eng @sahrens changed/removed the useNativeAccessor behaviour, so I hope this issue was also fixed with the next/upcoming minor release 0.60.0. 🙌

(I couldn't test the new version yet, because running from the npm package (also with sourcecode changes) works fine for me, but the sourcecode version of RN let fail some of my 3rd party libraries. I'm looking forward for a RC of 0.60.0 and maybe will update this text here then.)

@AurelienLW
Copy link

Hello there, i've been trying to do this the past week, and still have no clue how to deal with cookie-based Auth.

SendRequest = async () => {

         fetch('POST', 'MyURL', {            
                 'Content-Type' : 'application/json',
                 'Authorization' : 'XXXXXXXXX',
                 'credentials': 'include',
                 'cookie' : 'cookie1=blablabla; cookie2=blablabla cookie3=blablabla; cookie4=blablabla; cookie5=blablabla; cookie6=blablabla; cookie7=blablabla;'
             }, {"data1":"hello", "data2":"there", "data3":"obiwankenobi"})
        .then((response) => response.json())
        .catch((error) => {
           console.error(error);
        });

    }

my url is https, still added android:usesCleartextTraffic="true"
i've used curl for testing the request, and everything works fine.

i'm getting a Network request failed with no hint of how to resolve it.
if you have any update on the topic it'd be great.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 2, 2019
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Ran Commands One of our bots successfully processed a command. Resolution: For Stack Overflow A question for Stack Overflow. Applying this label will cause issue to be closed. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests