I am using `CefSharp.Wpf` to display my Angular SPA in WPF. 

My authentication is based on JWT tokens, which are stored in browser local storage. I call dialog with CefSharp and login (save JWT in local storage).

Then, I want my c# app to be able to make api calls to protected resources of API. For that purpose I need to retrieve token from local storage and add it in request headers. 

But I can not find the way to get data from local storage using my client c# code. How can I implement this?
['https://Stackoverflow.com/questions/35983961', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2866189/']
`CEF` doesn't provide any `API` for this, so you can use `JS` or manupulate your `.localstorage` file on disk with use of `sqlLite`.

I have achieved manipulation of `LocalStorage` with calling `JS` code. This article has helped a lot: <https://blog.logrocket.com/the-complete-guide-to-using-localstorage-in-javascript-apps-ba44edb53a36/>

In my case

```
var _browser = new ChromiumWebBrowser();

```

JS wrappers:

```
public void RunJavascript(string script)
{ //semicolumn at the end is not needed, multiple semicolons don't cause error
   _browser.GetMainFrame().ExecuteJavaScriptAsync(script);
}
public dynamic RunEvaluateJavascript(string script)
{
    string scriptTemplate = @"(function () {
                                return " + script + ";" +
                            "})();";

    Task<JavascriptResponse> t = _browser.GetMainFrame().EvaluateScriptAsync(scriptTemplate);
    t.Wait();

    return t.Result.Result;
}
public string RunEvaluateJavascriptToString(string script)
{
    var res = RunEvaluateJavascript(script);
    return res == null ? null : res.ToString();
}

```

LocalStorage functions:

```
public Dictionary<string, string> GetAllLocalStorageVariables()
{
    dynamic res = RunEvaluateJavascript("{ ...localStorage };");
    Dictionary<string, string> dictRes = null;

    try
    {
        var dictTmp = new Dictionary<string, object>(res);
        dictRes = dictTmp.ToDictionary(k => k.Key, k => k.Value.ToString());
    }
    catch
    {
        return null;
    }

    return dictRes;
}
public string GetLocalStorageValue(string key)
{
    return RunEvaluateJavascriptToString($"window.localStorage.getItem('{key}');");
}
public void SetLocalStorageVariable(string key, string value)
{
    RunJavascript($"window.localStorage.setItem('{key}', '{value}');");
}
public void ClearLocalStorage()
{
    RunJavascript("window.localStorage.clear();");
}
public void RemoveLocalStorageKey(string key)
{
    RunJavascript($"window.localStorage.removeItem('{key}');");
}

```
I also encountered this problem, which is the result of my research.  

First, `CEF` does not provide such a function of `API`.  

But we can use JavaScript object binding to realize this function.  

step 1：in c# Register a JavaScript object like this:

```
JavascriptObjectRepository.Register("localStorage_hook", LocalStorage);

```

Some ways to implement storage, such as 

```
public object GetItem (string host, string key);

```

setp 2: in javascript Delete the original localStorage object, like this:

```
cefSharp.deleteBoundObject ('localStorage');

```

and bind our object 

```
cefSharp.bindObjectAsync('localStorage_hook');

```

set 3: in javascrti Create a Proxy object to transfer and implement the attributes and methods of localStorage, like this:

```
localStorage = new Proxy({ 
    get length() { return localStorage_hook.getItemsCount(location.origin); },
    key: function (idx) { return localStorage_hook.getKey(location.origin, idx); },
    getItem: function (key) {return localStorage_hook.getItem(location.origin, key);},
    setItem: function (key, value) {return localStorage_hook.setItem(location.origin, key, value);},
    removeItem: function (key) {return localStorage_hook.removeItem(location.origin, key);},
    clear: function () {return localStorage_hook.clearItems(location.origin);}
    },
    {
        get(obj, name) {
            if (obj[name]) {
                return obj[name];
            } else {
                return obj.getItem(name);
            }
        },
        set(obj, name, value) {
            obj.setItem(name, value);
        }
    });

```