ios - 设置 Xamarin WebView Cookie 以无缝验证用户身份,无需重新输入凭据

标签 ios xamarin.forms webview uiwebview session-cookies

我有一个 Xamarin 表单移动应用程序,用户使用后 REST API 进行身份验证,我将保存返回的 ASP.NET session ID 和身份验证 cookie,以便稍后将其传递到主页中的 WebView 以加载需要认证的网页。为此,我创建了一个自定义 Web View 渲染器,并遵循了一些指南,这些指南建议如何将 Cookie 容器中的 Cookie 传递给每个请求的 WebView。但这不起作用,我进入了我们网站的登录页面。请指教。

WebView 渲染器(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 View 。然后,特定于平台的实现会获取 cookie,您可以从 pcl-webview 使用它。

安卓

var cookieHeader = CookieManager.Instance.GetCookie(url);

iOS

NSHttpCookieStorage storage = NSHttpCookieStorage.SharedStorage;

您可以查看https://github.com/seansparkman/CookiesWebView了解更多详情。

关于ios - 设置 Xamarin WebView Cookie 以无缝验证用户身份,无需重新输入凭据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57051774/

相关文章:

ios - 如何永久显示 UIScrollView 滚动条而不是闪烁?

xamarin.forms - 如何设置直接托管在 Xamarin Forms 上的 Web Api 端点?

visual-studio - 预览 Xamarin 表单页面

android - Xamarin Forms ToolBarItem(图标上的数字)通知

webview - 我可以将 JavaScript 和 CSS 注入(inject) Xamarin Form WebView 中吗?

ios - 单独的字符串 : 2 labels

ios - EAGLContext_presentRenderBuffer 在 OpenGLES 压力测试中占用了大部分时间

ios - 无法将类型 '(_) -> ()' 的值分配给类型 '((String, String, String, Int) -> ())?'

android - 前台服务 onTaskRemoved 发送广播 Intent 失败 android.os.DeadObjectException

javascript - 将本地网络应用程序包含到 native webview 中