问题
I have a Xamarin forms mobile app where the user authenticates using a post REST API and I am going to save the returned ASP.NET session ID and the authentication cookie to later pass it to my WebView in the main page to load a web page that needs authentication. For this, I created a custom web view renderer and followed some guides that suggested how to pass the cookie in the cookie container to the WebView for each request. But that does not work and I get to the login page of our website. Please advise.
WebView Renderer (IOS):
[assembly: ExportRenderer(typeof(CookieWebView), typeof(CookieWebViewRenderer))]
namespace perfectmobile.iOS
{
public class CookieWebViewRenderer: WebViewRenderer
{
public CookieWebView CookieWebView
{
get { return Element as CookieWebView; }
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Delegate = (UIKit.IUIWebViewDelegate)new WebViewDelegate(CookieWebView);
}
}
}
internal class WebViewDelegate : UIWebViewDelegate
{
private CookieWebView _cookieWebView;
public WebViewDelegate(CookieWebView cookieWebView)
{
_cookieWebView = cookieWebView;
}
public override bool ShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
{
// Set cookies here
var cookieJar = NSHttpCookieStorage.SharedStorage;
cookieJar.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;
//clean up old cookies
foreach (var aCookie in cookieJar.Cookies)
{
cookieJar.DeleteCookie(aCookie);
}
//set up the new cookies
var jCookies = _cookieWebView.Cookies.GetCookies(request.Url);
IList<NSHttpCookie> eCookies =
(from object jCookie in jCookies
where jCookie != null
select (Cookie)jCookie
into netCookie
select new NSHttpCookie(netCookie)).ToList();
foreach (var ck in eCookies)
{
cookieJar.SetCookie(ck);
}
return true;
}
public override void LoadFailed(UIWebView webView, NSError error)
{
// TODO: Display Error Here
Debug.WriteLine("ERROR: {0}", error.ToString());
}
public override void LoadingFinished(UIWebView webView)
{
}
}
}
//===================PCL project Cookie webview ========//
public class CookieWebView : WebView
{
public static readonly BindableProperty CookiesProperty = BindableProperty.Create(
propertyName: "Cookies",
returnType: typeof(CookieContainer),
declaringType: typeof(CookieWebView),
defaultValue: default(string));
public CookieContainer Cookies
{
get { return (CookieContainer)GetValue(CookiesProperty); }
set { SetValue(CookiesProperty, value); }
}
public CookieWebView()
{
Cookies = new CookieContainer();
}
}
//========= Login ======//
var handler = new HttpClientHandler();
handler.CookieContainer = UserInfo.CookieContainer;
HttpClient client = new HttpClient(handler);
HttpContent content = new StringContent("");
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
Uri uri = new Uri(LoginUrl);
var response = client.PostAsync(uri,content);
var responseResult = response.Result;
if (responseResult.IsSuccessStatusCode)
{
IEnumerable<Cookie> responseCookies = UserInfo.CookieContainer.GetCookies(uri).Cast<Cookie>();
foreach (Cookie cookie in responseCookies)
{
UserInfo.CookieContainer.Add(uri, cookie);
}
}
//======== User Info =======//
public class UserInfo
{
public static CookieContainer CookieContainer = new CookieContainer();
}
// ======== Main Page Xaml =======//
<local:CookieWebView x:Name="webView" Source="Url of the website page " WidthRequest="1000" HeightRequest="1000" />
//========= Main page.cs ==========//
public partial class MainTabbedPage : ContentPage
{
public MainTabbedPage()
{
InitializeComponent();
webView.Cookies = UserInfo.CookieContainer;
}
回答1:
You need to create a custom control in your PCL-Project and then add a custom webview for each platform. The platform secific implementation then gets the coockies and you can use it from your pcl-webview.
Android
var cookieHeader = CookieManager.Instance.GetCookie(url);
iOS
NSHttpCookieStorage storage = NSHttpCookieStorage.SharedStorage;
And you can check https://github.com/seansparkman/CookiesWebView for more details .
来源:https://stackoverflow.com/questions/57051774/set-xamarin-webview-cookie-to-seamlessly-authenticate-user-without-re-entering-c