Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Shared Auth across multiple WebViews

Milner99Milner99 Member ✭✭

Hi Everyone,

I have a MasterDetailPage setup where I can load a detail page which presents a webview - in that webview I sign in to a secure website. That works fine.

I then change the menu bar (Master) in my MasterDetailPage and allow access to lists of pages, including a RSS list which onwardly loads (via Naviation.PushAsync(new page1())) web views that are behind the same authentication that I passed a few seconds ago.

This time however I am pushed back to the sign in page?? Any know how I can force or keep the authentication session live between web views?

I'm sure this has been tackled before, fixed before or solutions created before - it must be a common issue but I just can't seem to find a solution.

Any and all help is greatly appreciated.

Thank you

Answers

  • Milner99Milner99 Member ✭✭

    Bump :smile:

  • ColeXColeX Member, Xamarin Team Xamurai

    Try to customize your own webview , create cookies function ,reset the cookies when relaunch webview .

    check

    https://forums.xamarin.com/discussion/41039/setting-cookies-in-a-webview
    https://github.com/seansparkman/CookiesWebView

  • Milner99Milner99 Member ✭✭

    Thanks for taking time to answer ColeX. Sadly that didn't work. The cookies already exist in the new web view but it seems to simply ignore them. V.strange.

    I was using Xamarin.Form 4.5 - nothing worked with that. I have rolled back to Xamarin.Forms 4.2 and magically it works now. I'm yet to do any more research as to why but potentially a bug? If I get time which I hope I will I'll do some more tests and try to narrow down why it's not working but for now, my fix is to roll back - now it's working.

  • ColeXColeX Member, Xamarin Team Xamurai

    Xamarin.forms 4.5 removes WebViewRenderer and use WKWebViewRenderer now, which means the webview we use in forms project would be rendered into WKWebview on iOS , maybe it is the cause in your situation .

    Check https://docs.microsoft.com/en-us/xamarin/xamarin-forms/release-notes/4.5/4.5.0.

  • Milner99Milner99 Member ✭✭

    Good point. I suppose this change is mandatory by Dec 2020 when apple decommission UIWebView.

    For now I stick with Xamarin.Forms 4.2 as I've got a deployment to do, then spend more time when there is more time to figure out how to share cookies between SharedCookieStore and the WKWebViewRenderer.

    Appreciate all your help.

  • Milner99Milner99 Member ✭✭
    edited April 2020

    Revisiting this issue with shared cookies as it's causing a me sleepless nights!

    I've moved to Xamarin.Forms 4.5 - WKWebView as standard - but the for life of me I can't get a signed in session state to work across all my views in iOS.

    • Tried, standard <WebView.../>
    • Tried, HybridWebView (WkWebViewRenderer) and injecting cookies into the WkWebView I create, or a new var config = WKWebViewConfiguration() which I pass to the new WkWebView(Frame, config). having "SetCookie" performed on it. when debug I can see the cookies I want.
    • Tried even creating an instance of my ContentPage in the App.xaml.cs as 'public static ContentPage' then using that to display all web views hoping that as it's 'in memory' it would keep the active session live

    literally nothing is working. I have to missing something and I need some help please forum.

    Every time I use <WebView.../> or <local:HybridWebView.../> I seem to get a brand new instance of a WkWebView and no cookies exist so I'm always pushed to a login page.

    My goal is to load a WebView from a page containing a ListView, just a RSS reader and show a news article. This news article is behind a login which I've passed previously within the app on a webview successfully to authenticate. Again here I've seen the cookies come back and exist.

    My HybridWebView:
    `public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>
    {
    WKWebView wkWebView;
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);
    var h = e.OldElement as HybridWebView;

                if (Control == null)
                {
    
                    NSHttpCookie[] nsHttpCookies = NSHttpCookieStorage.SharedStorage.Cookies;
                    var config = new WKWebViewConfiguration();
                    foreach (var c in nsHttpCookies)
                    {
                        config.WebsiteDataStore.HttpCookieStore.SetCookie(c, null);
                    }
    
                    wkWebView = new WKWebView(Frame, config);
                    wkWebView.CustomUserAgent = "--------";
                    SetNativeControl(wkWebView);
                }
    
                if (e.NewElement != null)
                {
    
                    //wkWebView.LoadRequest(new NSUrlRequest(new NSUrl(Element.Url)));
                    Console.WriteLine("URL Using in LoadRequest" + App.DisplayArticle.target_url);
                    Control.LoadRequest(new NSUrlRequest(new NSUrl(App.DisplayArticle.target_url)));
                }
            }
        }`
    

    Literally nothing is helping me ensure the cookies that show a logged in state or session are transferred over to the new WebView

    I'm either doing something very wrong, missing something obvious or it's not possible - whatever the answer I would LOVE some guidance please!

  • ErdoganErdogan Member ✭✭✭

    I couldn't publish my app because of this problem for 2 months. There is no solution yet :/ But the problem is in the new WkWebView (iOS 13 and above) not about Xamarin. Meanwhile, you should test your app on the real device when you should test the cookies, not in the simulator.

  • I found this issue when searching for a solution to the same problem. I actually create my cookie container by doing a separate call to the server using an HttpClient beforehand, then I assign the same cookie container to my WebViews when creating them. For some reason this would only work for the first WebView I create and not subsequent ones, despite the fact that I can see that the cookie in the store is still there and is still the same.

    The solution for me was to not re-use the same cookie container object. Instead, I store the cookie container from my HttpClient call, and every time I create a WebView, I make a copy of that container and use it. Then all of a sudden it worked for me.

    I found code on Stack Overflow to make a copy of the cookie container. I would link to that answer but apparently I'm not allowed to post links yet, so here's the code:

    private CookieContainer CopyContainer(CookieContainer container) { using(MemoryStream stream = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, container); stream.Seek(0, SeekOrigin.Begin); return (CookieContainer)formatter.Deserialize(stream); } }

  • Milner99Milner99 Member ✭✭

    @danniefraim said:
    I found this issue when searching for a solution to the same problem. I actually create my cookie container by doing a separate call to the server using an HttpClient beforehand, then I assign the same cookie container to my WebViews when creating them. For some reason this would only work for the first WebView I create and not subsequent ones, despite the fact that I can see that the cookie in the store is still there and is still the same.

    The solution for me was to not re-use the same cookie container object. Instead, I store the cookie container from my HttpClient call, and every time I create a WebView, I make a copy of that container and use it. Then all of a sudden it worked for me.

    I found code on Stack Overflow to make a copy of the cookie container. I would link to that answer but apparently I'm not allowed to post links yet, so here's the code:

    private CookieContainer CopyContainer(CookieContainer container) { using(MemoryStream stream = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, container); stream.Seek(0, SeekOrigin.Begin); return (CookieContainer)formatter.Deserialize(stream); } }

    Thanks mate - I ended up doing exactly this and it all works now.

    I did simulator and device testing.

    Now apple turn down the app for other more "business" reasons not code - more frustraiting!

Sign In or Register to comment.