Reputation: 246
I am running Edge WebView2 with some login page loaded there. I want to make an automatic login.
To do that I need to remove current cookies. I can’t do that via js because they are httponly. For Edge beta browser I wrote simple Chrome extension for deleting cookies, but I can’t run an extension in WebView2 (or can?).
Also I know where the WebView2 cookies file is situated but I can’t change it while Webview is running.
The only way to do that in WebView is open DevTools, I removed them in application tab.
Any ideas on how to delete that cookies?
I would appreciate at least example of WebView2 page loading with custom header (where I can specify cookies) in c++.
Upvotes: 2
Views: 10077
Reputation: 31
You may try below code to create, update and get the cookies from WebView
#include <string>
#include <tchar.h>
#include <wrl.h>
#include <wil/com.h>
#include "WebView2.h"
using namespace Microsoft::WRL;
std::wstring uri = L"https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
static wil::com_ptr<ICoreWebView2Controller> webviewController;
static wil::com_ptr<ICoreWebView2> webview;
static wil::com_ptr<ICoreWebView2_2> webview2;
static wil::com_ptr<ICoreWebView2CookieManager> cookieManager;
static wil::com_ptr<ICoreWebView2Cookie> cookie;
void WebView2Initialise(HWND & hWnd)/*HWND of MainWindow, call this after Window initialisation */ {
//Create a single WebView within the parent window
//Locate the browser and set up the environment for WebView
CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
[hWnd](HRESULT result, ICoreWebView2Environment* env) -> HRESULT{
// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd
env->CreateCoreWebView2Controller(hWnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[hWnd](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
if (controller != nullptr) {
webviewController = controller;
if (webviewController)
{
webviewController->get_CoreWebView2(&webview);
if (webview)
{
webview->QueryInterface(IID_PPV_ARGS(&webview2));
webview2->get_CookieManager(&cookieManager);
}
}
}
// Add a few settings for the webview
// The demo step is redundant since the values are the default settings
wil::com_ptr<ICoreWebView2Settings> settings;
webview->get_Settings(&settings);
if (settings)
{
settings->put_IsScriptEnabled(TRUE);
settings->put_AreDefaultScriptDialogsEnabled(TRUE);
settings->put_IsWebMessageEnabled(TRUE);
}
// Resize WebView to fit the bounds of the parent window
RECT bounds;
GetClientRect(hWnd, &bounds);
webviewController->put_Bounds(bounds);
std::wstring uri = L"https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
// Schedule an async task to navigate to Bing
webview->Navigate(uri.c_str());
if (cookieManager)
{
//Create Cookies
cookieManager->CreateCookie(L"CookieName", L"CookieValue", uri.c_str(), L"/", &cookie);
cookieManager->AddOrUpdateCookie(cookie.get());
cookieManager->GetCookies(
uri.c_str(),
Callback<ICoreWebView2GetCookiesCompletedHandler>(
[](HRESULT error_code, ICoreWebView2CookieList* list) -> HRESULT {
std::wstring result;
UINT cookie_list_size;
list->get_Count(&cookie_list_size);
if (cookie_list_size == 0)
{
result += L"No cookies found.";
}
else
{
result += std::to_wstring(cookie_list_size) + L" cookie(s) found";
if (!uri.empty())
{
result += L" on " + uri;
}
result += L"\n\n[";
for (UINT i = 0; i < cookie_list_size; ++i)
{
wil::com_ptr<ICoreWebView2Cookie> cookie;
list->GetValueAtIndex(i, &cookie);
if (cookie.get())
{
LPWSTR value;
cookie->get_Value(&value);
result += value;
if (i != cookie_list_size - 1)
{
result += L",\n";
}
}
}
result += L"]";
}
::MessageBox(NULL, result.c_str(), L"Cookies", MB_OK);
return S_OK;
})
.Get());
}}
Upvotes: 1
Reputation: 11230
Update: There is now an official ICoreWebView2CookieManager that can be used for managing cookies. Microsoft documents this API extremely well -- so its best to check their documentation.
With this new API, its just a matter of calling either DeleteCookie
to delete a single cookie, DeleteCookies
to remove all cookies from a domain, or DeleteAllCookies
to clear all cookies under the same profile.
(The original answer is retained below)
WebView2 is still in active development, and does not yet have a cookies API -- although it is a request that they are aware of.
The currently recommended approach to clearing/deleting cookies is to use ICoreWebView2::CallDevToolsProtocolMethod
and issue a Network
command. This is also what Microsoft demonstrates in their sample browser application to delete all cookies. Using the DevTools
API will still work, even if front-end UI devtools are not enabled in the application.
The parameters supplied to the command must be in JSON format, so if you want to delete a specific cookie using Network.deleteCookies
, you will need to supply {"name":"<cookie name>;"}
to delete <cookie name>
:
m_view->CallDevToolsProtocolMethod(L"Network.deleteCookies", L"{\"name\": \"<cookie name>\";}", nullptr);
Or alternatively you can delete all cookies with Network.clearBrowserCookies
:
m_view->CallDevToolsProtocolMethod(L"Network.clearBrowserCookies", L"{}", nullptr);
Note: The CallDevToolsProtocolMethod
is issued asynchronously, and so if you may need to supply a handler argument if you are needing the cookie deleted before proceeding.
Upvotes: 5