Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintain Cookies UIWebView iOS Xamarin

I have a UIWebView which Authenticates a user. I want to enable single Sign on. For this I want to store the cookies when the user is first authenticated and then the next time he starts the app, the cookies should automatically be passed to the UIWebView and authenticate the user without him entering his credentials again.

Iam doing something like below to use the UIWebView

var uri = new Uri(AuthUrl);
           var nsurl = new NSUrl(uri.GetComponents(UriComponents.HttpRequestUrl, UriFormat.UriEscaped));
           wvLogin.LoadRequest(new NSUrlRequest(nsurl));

CookieManager.cs

public static void SaveCookies()
{

   var cookieData = new NSMutableArray ();
   var cookieStorage = NSHttpCookieStorage.SharedStorage;
   foreach (var nscookie in cookieStorage.Cookies) {
    var cookieDictionary = new NSMutableDictionary ();
    cookieDictionary.Add (NSHttpCookie.KeyName, new NSString (nscookie.Name));
    cookieDictionary.Add (NSHttpCookie.KeyValue,new NSString ( nscookie.Value));
    cookieDictionary.Add (NSHttpCookie.KeyDomain,new NSString ( nscookie.Domain));
    cookieDictionary.Add (NSHttpCookie.KeyPath, new NSString (nscookie.Path));
    cookieDictionary.Add (NSHttpCookie.KeySecure, new NSString ( nscookie.IsSecure.ToString()));
    cookieDictionary.Add (NSHttpCookie.KeyVersion, new NSString (nscookie.Version.ToString()));
    if (nscookie.ExpiresDate != null) {
     cookieDictionary.Add (NSHttpCookie.KeyExpires, nscookie.ExpiresDate);
    }
    cookieData.Add (cookieDictionary);
   }
   cookieData.WriteToFile (StoragePath(), true);
}
  public static string StoragePath()
  {
   //var paths = NSSearchPath.GetDirectories (NSSearchPathDirectory.LibraryDirectory, NSUserDomainMask, true);
   var paths =  NSSearchPath.GetDirectories(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomain.User, true);
   return paths [0].ToString ();
  }
public static void DeleteCookies()
{
NSHttpCookieStorage cookieStorage = NSHttpCookieStorage.SharedStorage;
foreach (var nscookie in cookieStorage.Cookies)
{
cookieStorage.DeleteCookie(nscookie);
}
   NSUserDefaults.StandardUserDefaults.Synchronize ();
}
  public static void LoadCookies()
  {
   var cookies = NSMutableArray.FromFile (StoragePath());
   var cookieStorage = NSHttpCookieStorage.SharedStorage;
   foreach (var nscookie in cookieStorage.Cookies)
   {
    cookieStorage.SetCookie(nscookie);

   }
  }

LoginScreen.cs

void wvLogin_LoadFinished(object sender, EventArgs e)
    {
    int redirectCount = 0;
    redirect = System.Net.WebUtility.UrlDecode(wvLogin.Request.Url.AbsoluteString);
     // Do some stuff
    CookieManager.SaveCookies();

    }
    }
    else
    {
    AppDelegate.Logout();
    }
    }
    } 

How can I achieve this? Any help is appreciated as Iam new to iOS and Xamarin.

like image 908
hello world Avatar asked Jan 08 '16 04:01

hello world


2 Answers

You can setup the server to issue persistent cookie by setting a suitable expiry date. UIWebview will store/restore such cookies.

You could also get all cookies set by the sign-in in the UIWebView from NSHTTPCookieStorage as save in NSUserDefaults on in the keychain. You could read the cookies from NSUserDefaults/keychain on app launch, insert the same into NSHttpCookieStorage and they will be available for use by UIWebView and also the NSURLConnection, NSURLRequest etc.

like image 174
Anand Biligiri Avatar answered Nov 08 '22 22:11

Anand Biligiri


I would recommend using a sfSafariViewController.

SafariViewControllers have access to Safari's cookie storage. The advantage of SafariViewControllers is that you mostly everything is dealt with for you and implementation is extremely easy.

For security SafariViewController's are sandboxed from the rest of the app to protect cookies etc.

But if in your webservice you implement an API to redirect to a custom url with cookie data attached e.g. com.app://name/bob/age/12 and you setup com.app as a custom URL scheme in your app then you can redirect back to your app with cookie data.

The advantage of SafariViewControllers is that the user will still be logged into your service if they were to navigate to your website in safari.

Here is an example of how to implement all this. You can clone this repo and run it to try it for yourself.

Hope this is helpful to you,

Liam

like image 22
Liam Ferris Avatar answered Nov 09 '22 00:11

Liam Ferris