Case Studies



We encountered an issue that was quite difficult to track down and wanted to share what we learnt

In our case, we had a prototype site with .net core 2.2, react working, but we found on some browsers user tests failed, where others were fine (Windows 10  and Chrome 77+ and Samsung 9 and 10 Chrome and Safari on iPhone X)

But for iPhone 8 (Safari), Samsung 6 (Internet) and other legacy browsers such as IE 11 and EDGE we had a major problem. Users could not log in and got caught in a login, redirect loop back to the login page.

After debugging this we realised that in some cases the .net auth cookies do not get sent back to the server in a fetch request. The cookies were being set fine, but they were not being included in the post back so subsequent posts back on other pages, the user was treated and not logged in and sent back to the login page.

Using Fetch in legacy applications is tricky because in some cases the Fetch feature is native to the browser and the behaviour is just different. We found the one trick to make the credentials cookie pass back to the web service:

 credentials: 'same-origin'

 

We had to add the above to every fetch request throughout our system to cater for legacy browsers.

//authenticate user
        fetch('api/Login/AuthenticateUser', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',                
            },
            credentials: 'same-origin',
            body: JSON.stringify(datax)
        }).then(response => response.json())
            .then(data => { use data here }
            );

 

in other more simpler fetch requests it just looks like this:

fetch('api/Login/IsAuthenticated', { credentials: "same-origin" })
            .then(response => response.json())
            .then(data => {
                console.log('isAuthenticated:' + JSON.stringify(data));
                if (data.message === 'true') { this.setState({ isAuthenticated: true, username: data.dataobject.username }); }
                else {
                    this.setState({ isAuthenticated: false, username: '' });
                }
            });



Our authentication setup incase you want to validate yours.

 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options => {
            options.LoginPath = "/";
            // Cookie settings
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromDays(30);
            options.SlidingExpiration = true;
            options.LoginPath = "/Login/";
            options.AccessDeniedPath = "/AccessDenied";
            options.SlidingExpiration = true;
        });


It is also recommended through other sites I found to set cookie option is essential to true, incase any browsers have a requirement that there must be permission first, but as yet we have not tested this

options.Cookie.IsEssential = true;


This took me days to identify and fix and I wanted to help anyone else out who is looking at this problem specifically.




Top