MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
449 stars 55 forks source link

Cookies are not saved when Webview2 is displayed using .show() method #2128

Open SandhyaArun opened 2 years ago

SandhyaArun commented 2 years ago

My webview2 Control resides in a form and i am trying to show it from another form using ShowDialog() and Show(). The url I am displaying needs authentication and I want to skip the authentication when I load it second time. It wont ask for authentication during the second time, if I show the from using .ShowDialog() function. However if I use .Show() function , it is always ask for authentication. Cookies are not saved when it was displayed using .show() method. Can any one help me. Sample code is attached.

    public partial class StartForm : Form
    {
        public StartForm()
        {
            InitializeComponent();
        }

        private void LaunchModalWindowbutton_Click(object sender, EventArgs e)
        {
            WebForm webForm = new WebForm();
            webForm.ShowDialog();
        }

        private void LaunchNonModalWindowButton_Click(object sender, EventArgs e)
        {
            WebForm webForm = new WebForm();
            webForm.Show();
        }
    }

 public partial class WebForm : Form
    {
        private string m_url = "http://ottdev-cs.otxlab.net/CS/llisapi.dll/app/";
        public WebForm()
        {
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
        }

        private async void webView_NavigationCompletedAsync(object sender, CoreWebView2NavigationCompletedEventArgs e)
        {
            var cookies = await webView.CoreWebView2.CookieManager.GetCookiesAsync(null);
            for (int i = 0; i < cookies.Count; i++)
            {
                Console.WriteLine("Cookie Name = {0} Value = {1}", cookies[i].Name, cookies[i].Value);
            }
        }

        private async void WebForm_LoadAsync(object sender, EventArgs e)
        {
            await webView.EnsureCoreWebView2Async();
            if (!string.IsNullOrWhiteSpace(m_url) && webView != null && webView.CoreWebView2 != null)
            {
                var cookies = await webView.CoreWebView2.CookieManager.GetCookiesAsync(null);
                for (int i = 0; i < cookies.Count; i++)
                {
                    Console.WriteLine("Cookie Name = {0} Value = {1}", cookies[i].Name, cookies[i].Value);
                }
                webView.CoreWebView2.Navigate(m_url);
            }
        }
    }
}

WebView2SampleApp.zip

champnic commented 2 years ago

Hey @SandhyaArun - thanks for the bug report!

The difference between Show and ShowDialog is that ShowDialog will not call Close on the children controls when it is closed, and instead stays alive but hidden. This is keeping the WebView2 control alive, and is why the cookies are still there the next time you show the dialog. On the contrary, Show will call Close on the children which shuts down the WebView2 control.

I'm unable to access the url in the sample app your provided. Can you verify that the cookies are setup to be persisted, and aren't session cookies that would get cleaned up when the browser processes shut down?

Thank!

SandhyaArun commented 2 years ago

@champnic I tried to persist the cookies by calling CoreWebView2.CookieManager.AddOrUpdateCookie() and it is not working. Is it the right way to persist cookies window close? if not please advise me with right solution. Also I want to know is there a way to persist bowser state. not just the cookies?

My requirement is to create an instance of the browser, take the cookies it has collected via login, then when opening a new instance of the browser, pass those cookies to it so it can already be "logged in". I can manually do this cookie handling. I just wanna know webview2 is providing an easy way to achieve this.

    private async void webView_NavigationCompletedAsync(object sender, CoreWebView2NavigationCompletedEventArgs e)
    {
        var cookies = await webView.CoreWebView2.CookieManager.GetCookiesAsync(null);
        for (int i = 0; i < cookies.Count; i++)
        {
            Console.WriteLine("Cookie Name = {0} Value = {1}", cookies[i].Name, cookies[i].Value);
            webView.CoreWebView2.CookieManager.AddOrUpdateCookie(cookies[i]);
        }
    }
champnic commented 2 years ago

The WebView2 matches the cookie handling of the browser. Cookies that are marked with an expiration date (and not session cookies) will automatically be persisted. As long as you use the same User Data Folder when creating the new WebView2 instances, they will share cookies and browser state.

carlin-q-scott commented 1 year ago

I'm re-using my User Data Folder and Profile name, and the cookies are not persisting like they do with MS Edge. I'm using Azure Portal to test. My configuration looks like this:

var userDataPath = Environment.ExpandEnvironmentVariables("%USERPROFILE%\\AppData\\Local\\Microsoft");
var envOptions = new CoreWebView2EnvironmentOptions(allowSingleSignOnUsingOSPrimaryAccount: true);
var environment = await CoreWebView2Environment.CreateAsync(userDataFolder: userDataPath, options: envOptions);

var options = environment.CreateCoreWebView2ControllerOptions();
options.ProfileName = "Default";
options.IsInPrivateModeEnabled = false;

await webView2Control.EnsureCoreWebView2Async(environment, options);

The User Data and Profile is being created with lots of files and folders, so I don't think I'm running into a permission issue.