iOS App Login Flow - iphone

I've developing my first iOS app which allows users to login to an account on our website, and view / add / edit / delete records in a database.
I've written a basic app which handles the process like this;
App starts running.
Each view controller calls a checkAuth method from within the viewWillAppear method. This method gets the username and password stored within the app, sends them to the server as GET variables in a dataWithContentsOfURL request. The resulting JSON is then checked, if the response is a failure, then an alert dialog is shown, and the user is taken to a different tab (I'm using a tab bar controller) where they are prompted to enter their login details.
Using this method, every time a different view controller takes over (each scene in my storyboard file), the auth method is called. This seems a little wasteful. Is there a better way of ensuring a users login credentials are correct?
Thanks.

Storing the username and password in the app is bad practice. If modifying the back end is within your control, it would be better to authenticate to the back end, and get back a token that is only good for that device.
From here, you pass the token along with each request, and if the back end determines you have logged out then it should return an error message. This way, the authentication would be checked on an ad-hoc basis and only when sending a request.
I see no reason to do it every time a view loads, unless there is a business requirement for this.

Why don't you use a "communication management" singleton for this? It would handle all the tasks of authenticating and communicating with the server, and each one of your controllers talks to it without directly interacting with the server.

You could have an inactivity session timeout: via NSTimer.
Set a session timeout marker on successful login (e.g. login time plus 10 minutes).
As the user uses the app keep updating the stored session timeout time to the current time plus 10 minutes (invalidate the timer and create a new one).
When app exits or goes into background invalidate the timer.
Have the timer call a logout method when the timer times out.
Oh, and don't store username/password in the app. Use the keychain to store them encrypted (if necessary to keep them local). I suggest only the username should be stored locally.

Related

How to handle session using Scala Play framework?

I have user login feature in my application. I used Scala Play Framework as controller. I create sessions using withSession('userId'->userIDValue) for different users. My application has a feature that there will be one super user and super user can delete user. Now what happens is that if super user deletes a user but that user is logged in then that user's session is running till cookie of browser expires. Play Framework is stateless; is there any way to solve this problem?
On incoming requests, I think you need to verify that a user is still active on the Play side, and not just only trust the session.
If that's an expensive operation, e.g., you have to make a database call to verify if a user is still active, then maybe you can use the Play Cache API. If you only have one Play server instance, then it should be pretty easy -- you can just set something in the cache when the super user deletes a user, and have the cache item expiration be longer than your cookie expiration. If you have multiple Play server instances, then it's tricker. :)

How to handle api token expiry in app

Our API returns a user auth code which has a session expiry (30 mins of inactivity). So, if we make an api call using the auth token it renews the session to 30 mins from the time of the call.
After 30 mins of inactivity the api returns an error saying that the token has expired. At this point we should request a new auth token.
However, the obvious way to do this (show the user the log in screen and get them to log in again) will mean cutting the user off in the middle of some functions in the app.
For instance, we have various view controllers with options and inputs which aggregate and submit one whole API call at the end of the process. If the session expires on the server whilst the user is filling out these inputs and views then they will be logged out when the API call is made, and they will lose their progress in these views.
There are two possible work arounds for this:
We set timers in the app ourself to make sure the user is logged out after 30 mins inactivity in the app. This means that they won't get logged out during a set of inputs, however this poses the issues that: the server API may still expire even though we are running our own timer. This won't work therefore.
We poll every 10 seconds or so to the server to ask if the API auth token is still valid. This will eat battery, data and all sorts and just isn't a reasonable way to do something like this.
Does anyone have any ideas?
Thanks
Tom
From your description, it sounds like a classic failed transaction problem. Just in case you are not familiar with transaction processing, "Nuts and Bolts of Transaction Processing" is a primer on the topic.
If you have the ability to modify the back end system, you will want to ensure an ACID backend.
This could mean building up data on the client and not send the data to the server until you have a complete transaction. That way, if the session times out, the client still has all the data needed to complete the transaction. (leverage atomicity)
This could mean having a transaction token. As a new session is created the client could send the server the transaction token and the state of the transaction is restored within the new session. (leverage durability)
To me both of these options are better than wiping out the existing transaction and forcing the user to start over again.
Hope that helps.

How do you keep a user persistently logged in on an iPhone app?

On my iPhone Facebook app I think I've only logged into it once.
On my Mint financial app, I've logged in once. whenever I load it back up, I give a four digit PIN number which was setup in the app, and I never have to log in again.
I'm building an application right now where this type of behavior would be highly beneficial.
Do they just set an auth cookie of some sort and just set it to expire way into the future? Or is there another way of handling this?
Thanks!
You can use the iOS KeyChain to securely store credentials as well. This can be simplified by using this code found on github ( https://github.com/ldandersen/scifihifi-iphone/tree/master/security/ ) , with some basic instructions found at http://gorgando.com/blog/tag/sfhfkeychainutils
That depends on the context of your application. If you authenticate against another API, the supplier of the API usually provides you with some sort of authentication key which might expire after a certain time. You would store this key in your application once the user performs the authentication step and reuse it for every request.
Basically, the data you have to store and the time before your user has to re-authenticate (if ever) depends on the supplier of the API you're using.
I can't speak for Facebook or Mint, but the simplest approach is to use a cookie / token and store it in NSUserDefaults.
When the application is launched, see if token is still valid. If not valid, force the user to sign in again.
I am taking a stab in the dark here, but:
I am assuming the login information is encrypted and then stored on the device somewhere. Upon creating a new instance of the app this data is sent to the site for all of the oauth/login/etc stuff. Once this is done the Facebook app stays on until: 1) the device is turned off, or 2) you manually quit the application.
Maybe this will start to help you, but I am sure better answers will come.

didRegisterForRemoteNotificationsWithDeviceToken - Push Notifications

I just wanted to confirm "didRegisterForRemoteNotificationsWithDeviceToken" is meant to be called everytime the application loads and my PHP server or application needs to deal with whether or not to resubmit to store in my database? Or is there something I am missing?
Thanks
James
First, you are not meant to call this method directly. Rather, you should call registerForRemoteNotificationTypes: on every launch of your app which then in turn calls application:didRegisterForRemoteNotificationsWithDeviceToken: which you must implement.
Second, yes, you are supposed to resubmit the token to your server every time. From the documentation:
By requesting the device token and passing it to the provider every time your application launches, you help to ensure that the provider has the current token for the device. If a user restores a backup to a device other than the one that the backup was created for (for example, the user migrates data to a new device), he or she must launch the application at least once for it to receive notifications again. If the user restores backup data to a new device or reinstalls the operating system, the device token changes. Moreover, never cache a device token and give that to your provider; always get the token from the system whenever you need it. If your application has previously registered, calling registerForRemoteNotificationTypes: results in iOS passing the device token to the delegate immediately without incurring additional overhead.

How to find if an Oracle APEX session is expired

Short version:
If the function wwv_flow_custom_auth_std.is_session_valid (or apex_custom_auth_std.is_session_valid) returns TRUE, is it possible that the session is expired but still alive? If so, how can you check if a session is expired?
Long version:
I have created a single-sign-on system for our Oracle APEX applications, roughly based on this tutorial:
http://www.oracle.com/technology/oramag/oracle/09-may/o39security.html
The only difference is that my master SSO login is in Perl, rather than another APEX app. It sets an SSO cookie, and the app can check if it's valid with a database procedure.
I have noticed that when I arrive in the morning, the whole system doesn't work. I reload a page from the APEX app, it then sends me to the SSO page because the session was expired, I logon, and get redirected back to my original APEX app page. This usually works except first thing in the morning. It seems the APEX session is expired. In that case it seems to find the session, but then refuse to use it, and sends me back to the login page.
I've tried my best to trace the problem. The "wwv_flow_custom_auth_std.is_session_valid" function returns true, so I'm assuming the session is valid. But nothing works until I remove the APEX session cookie. Then I can log back in easily.
Anybody knows if there is another call that would tell me if the session is expired or not?
Thanks
You can set the Maximum Session length in seconds under the application security attributes page.
Apex states the following:
"The session duration may be superseded by the operation of the job that runs every eight hours which deletes sessions older than 12 hours."
You could use the view apex_040100.APEX_WORKSPACE_SESSIONS to determine if a session is valid based on its existance or creation time. eg: session_created - systdate > 12Hours.
You should also use the "On session timeout direct to this URL" attribute.
This solution would require privileged access but you can query the wwv_flow_sessions$ view in your apex schema for any session that matches your username. If none exists, your session has timed out. This view also gives you a field 'idle_timeout_on' that will tell when your session is scheduled to time out.