Set cookies from the app to Safari in iOS - ios

In my app I need to implement next feature: when user logged-in in the app, it (the app) needs to save cookies (or any other data) for certain website to mobile Safari. The goal is to not make user log-in next time when he will open that website in Safari.
Documentation says that it can't be done on iOS using cookies. Does anybody know any other solution? Required feature of implementation is to make it 'silently' to user, without opening Safari.
UPDATE
Is it possible to access app data from mobile Safari and get some callback? For example when user browses website the site sends some callback to the app and gets some response with user' data.

Old question, but could you open Safari to a special one-time URL from your app which takes user to a page which you host, passing a token which you retrieve from API on same server, with page then validating token and setting cookie? That way authorization is handled on server, and server can set the cookie in the response.
You could do something like this in your app
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"https://myhost.com/myhandler?token=PX2G16BWFKZBQWUKGF3BGRY2Z6BEJ7Z3PMO2GZ6S3R00JVWBVEO6VWBEXNK14IBJ5GKAY5EKBLAHNSAJ8"]];
Then page at myhost.com/myhandler would read and validate token, and set cookie on response, and then invalidate the token. You could also add a time limit for how long the token could be used.

You can't access the safari cookies.
Safari's cookies are not accessible from other apps. Each app is given
its own WebKit cache and cookie stores, so while cookies will persist
within the same app, they aren't accessible between apps.

Related

Dropbox OAuth2 API always prompts user for permission when a refresh token is requested

I'm writing an offline application that uses the Dropbox API. When a user comes to the application, I'm using the https://api.dropbox.com/oauth2/token (docs) to get a refresh_token, which I store for later use.
I am calling the same endpoint every time the user logs in (unless I've already got the user's data in a cookie). I'm not sure that this is the best way to go about it: I at least need to get the user's account_id, so that I can look up their refresh_token in the database if I already have it. But every time I call https://api.dropbox.com/oauth2/token, the user is redirected to the Dropbox app authorization interface, as if they've never approved the app before.
So I would either like to know how to stop Dropbox from forcing the user to re-authorize an app every time. Or, if that is just how https://api.dropbox.com/oauth2/token is supposed to work, I'd instead like to be able to get their account_id somehow when they visit my page.
(In case it's relevant, the app is still in development mode at this point.)
The https://api.dropbox.com/oauth2/token endpoint is an OAuth endpoint that the app can call to get an access token/refresh token. Being an API endpoint, it does not itself redirect the user to the Dropbox app authorization page.
The Dropbox app authorization page is at https://www.dropbox.com/oauth2/authorize (documented here), and the app decides if/when to direct the user there to authorize the app.
You generally only need to send the user through the app authorization flow (sending them to https://www.dropbox.com/oauth2/authorize and then calling https://api.dropbox.com/oauth2/token) once per user for an "offline" application. Once you do so, you should store the resulting refresh token for that user. You'll typically store the refresh token for that user tied to their user account in your own app.
Exactly how you manage the user accounts in your own app will depend on how it's built, but, as it sounds like this is a web app, typically you would use the user's browser cookies to identify the user when they return to your page so that you can look them up in your database and retrieve their details, such as their corresponding refresh token. (Or, if they're not already signed in to your web app, you would have them do so first.)
Greg's answer is very helpful, and very politely addresses my misunderstanding of the auth flow. (I was revisiting old code I'd written years previously—obviously I should have documented it better than I had!)
In the end I believe that Dropbox was forcing me to reauthorize because my application was in development mode, and had a small user base. When I used the identical code in an app set to production mode, it stopped forcing me to reauthorize. So the “problem” is really a Dropbox security feature, and the solution was just to use production mode.

Cookies Enabled or Disabled

I have Disabled cookies for safari browser from settings. and now whenever I am going to login in facebook from my safari browser it's disallowed me.
So, My query is that how can I check from my app that cookies are enabled or disabled.
Or another thing is there anyway to login through facebook while cookies are disable from settings. From Instagram app it is possible.
Cookies is use for storing some information of site. so for next visit that cookies can use directly without user input.
Now in your case if you are not allowing cookies than it will not load your stored info. instead you have to add by your own to proceed.
It does not restrict any site or app.

How to to share context between Safari and Native App?

I have a need to set some context via Safari (a context token), and then read that context from a native iOS app. What are the best practices for doing this?
A couple thoughts so far:
Set the context in an HTML 5 database, but I'm not sure this will work because the database might be only accessible from Safari. Would using a WebUIView in the native app allow me to access the same HTML5 database / local storage as Safari?
Set the context in device storage, but I'm not sure this will work because I don't know if Safari can actually write to device storage.
I would suggest one of these two options:
Let the web server keep track on the user both in the app and on the website, for example by creating a user account.
or
Pass the context token to the app immediately via an URL-scheme by registering your app as a protocol handler, see more info here
Suggested way:
Send e-mail with link and context token, when user clicks link, save context token in cookie in safari, then redirect to appstore for app download.
When the user downloaded the app and opens it, present a button for the user, when the user clicks it, open a web page in safari.
Safari loads the cookie with the context token, and then triggers another link using a URL-scheme like yourAppName://contextToken=12345678. The link opens your app which reads the context token from the URL.
There is no best practice for directly sharing data between safari and a native app directly and that it is simply not intended that you should do that. All cookies and storages are sandboxed for each app and safari has its own sandbox.
Letting your server doing the job via user accounts is the best and clean way i.m.o. That is why you have user accounts. If you didn't try out the protocol handler for reading specific URLs, that could also be made handy I think.
Could you have the app hit a URL on first launch hosted by server which is redirecting the user in safari, and compare IP addresses, time, iOS version, etc to get at least an approximate match? If an approximate match is insufficient, you could, when you see an approximate match, have your app open safari to confirm their identify via cookie.
It’s easy to send messages between a UIWebView and your native up using WebViewJavascriptBridge.
In your case, though, the accepted answer’s suggestion of using a custom URL scheme (directly from email to app, post-install) makes the most sense.

keep "session only" cookies, iOS

I'm creating an app that connects to a website, and I don't want the user to need to enter their user credentials every time the app loads. The website returns a session cookie (no expiry date set). Is there any problem with me holding on to that cookie indefinitely? If I just reload it when the app starts, it seems to work.
Thanks!
Each application has its own cookie store. So if there is no expiration on the cookie, and you don't delete it, and the app isn't deleted, then there's no problem with using it for as long as you like.
EDIT Here are some links for more opinions and insight:
Persisting Cookies In An iOS Application?"
iPhone: NSHTTPCookie is not saved across app restarts
My opinion on the matter is that the mobile environment is fundamentally different from the desktop environment. "Quitting" a mobile application is in no way similar to quitting a desktop application. Quitting a mobile application is similar to switching focus on a desktop. You would not expect to re-authenticate every time you pressed Cmd-Tab.
Limiting the life of session tokens is a valuable security precaution, but is correctly implemented on the server side, not the client side. If the server is designed to allow a session to persist indefinitely (because the desktop app is never quit), then there is no reason to not continue the session on a mobile platform in a similar way.
Note that there are other solutions, such as storing the user credentials in keychain so that you can reuse them. This is appropriate in many cases, but it actually is a lower-security solution than persisting the session token indefinitely. If you're going to hold onto an authentication credential forever, it's better that it be a single-purpose token (i.e. a session cookie) rather than a multi-use username and password.
There is no problem in you allowing this cookie to be set, each application has a cookie store from which you can if you need to check the cookies, however I assume that since this is only a session cookie, you will only need to allow it's existence and let the user leverage the web service until such time the user logs out.
I have done this with some of my apps also.
Good luck.

Passing credentials to Safari from iOS app

I am working on an iOS app in Monotouch. Part of it is to connect to an exchange server and download a list of emails. I would like to include the ability to open the email in the OWA client as well (so I don't have to recreate a email client to provide features OWA gives me for free).
I don't want the user to have to input credentials again however. Opening OWA in safari would usually present the user with either a form or a pop up asking for username and password.
Say I have a user admin with password password1. Currently what I do is request safari to open a link in the following form:
https://admin:password1#mailserver/exchange
This passes the credentials to safari and bypasses the HTTP basic authentication that OWA would usually pop up, however it is not very safe and safari complains of a possible phishing attack.
What other options are there for performing this kind of bypass of HTTP basic authentication?
I would recommend using HttpWebRequest to download each page and set the UIWebView's text manually. Using HttpWebRequest gives you the flexibility to use whatever cookies, credentials, http headers, etc. you want.
This will be tricky, but probably the only way to safely get the credentials in there. Not sure if your OWA app will be able to handle it either.

Resources