设置 Xamarin WebView Cookie 以无缝验证用户身份而无需重新输入凭据 [英] Set Xamarin WebView Cookie to seamlessly authenticate user without re-entering credentials

查看:130
本文介绍了设置 Xamarin WebView Cookie 以无缝验证用户身份而无需重新输入凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 渲染器 (IOS):

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-Project 中创建一个自定义控件,然后为每个平台添加一个自定义 webview.平台特定实现然后获取 coockies,您可以从您的 pcl-webview 中使用它.

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.

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

iOS

NSHttpCookieStorage storage = NSHttpCookieStorage.SharedStorage;

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

And you can check https://github.com/seansparkman/CookiesWebView for more details .

这篇关于设置 Xamarin WebView Cookie 以无缝验证用户身份而无需重新输入凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆