我有一个 Xamarin 窗体移动应用程序,用户在其中使用后 REST API 进行身份验证,我将保存返回的 ASP.NET 会话 ID 和身份验证 cookie,以便稍后将其传递给主页中的 WebView,以加载需要身份验证的网页。为此,我创建了一个自定义 Web 视图呈现器,并遵循了一些指南,这些指南建议如何将 cookie 容器中的 cookie 传递给每个请求的 WebView。但这不起作用,我进入我们网站的登录页面。请指教。
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;
}
需要在 PCL 项目中创建自定义控件,然后为每个平台添加自定义 Web 视图。然后,特定于平台的实现会获取cookie,您可以从pcl-webview使用它。
人造人
var cookieHeader = CookieManager.Instance.GetCookie(url);
苹果
NSHttpCookieStorage storage = NSHttpCookieStorage.SharedStorage;
您可以查看 https://github.com/seansparkman/CookiesWebView 以获取更多详细信息。