I want to offer some paid content in the app but I don't want the user to go through an Authentication process. I would like him to enter the app and directly be able to buy some of the content and remember that this user has bought it if he comes back later or uninstall/reinstall the app later on. (Like most meditation app on the Store right now)
Is it possible using Firebase Services and if so, what would be the good way to track paid content for anonymous user?
An Anonymous user IS a user without details (Name, email, password, etc). It has a unique UserID
So YES. You can save anything to the database using the User's unique ID. But remember. Every app is capable of performing operations inside their sandbox directory. which also has a unique ID and resets when the app is uninstalled.
In a sentece. Firebase won't remember the Anonymous user ID if the app was deleted intentionally.
The docs does state this very well:
You can use Firebase Authentication to create and use temporary
anonymous accounts to authenticate with Firebase. These temporary
anonymous accounts can be used to allow users who haven't yet signed
up to your app to work with data protected by security rules. If an
anonymous user decides to sign up to your app, you can link their
sign-in credentials to the anonymous account so that they can continue
to work with their protected data in future sessions.
Read more:
Authenticate with Firebase Anonymously on iOS
You could theoretically set it up to where it would redirect the user to a TextField page asking him/her to make a "password" and "PIN" of sorts. This "password" and "PIN" could then be stored into a SQL server database as an anonymous user. When re-downloading the app you could have a page dedicated to purchase recovery where all a user would need to do is input this "password" and "PIN", after they have correctly entered both it would return purchases to their account.
things to be wary of:
-People may use the same password, which is why I recommended a PIN as a way of two-step authentication. Keep in mind also that your app will need to test the password against the server before uploading to make sure that the password doesn't already exist and tells the user that the password cannot be used in such case.
-This is essentially the same thing as an account with a username and password... the only difference is that you aren't going to be collecting other information on them, such as email and birthday, etc., making it more anonymous.
-This is a very rare case of question and I know this is a crappy answer, but honestly this isn't the best idea to implement unless your app heavily relies on it.
Related
I am in the process to design a login for a new app that will be associated with a domain, i.e. be the counterpart to an SPA.
Obviously I want to use
iOS 11 Password Autofill, and
Shared Web Credentials
I have read the documentation on autofill as well as watched the WWDC video about it. Also, I checked the article on Shared Web credentials, which I think is older than the new, reworked autofill. Said article recommends:
Do not use the shared web credentials as your primary storage for secure user credentials. Instead, save the user’s credentials in the keychain, and only use the shared web credentials when you can’t find the login credentials in the keychain.
This strikes me a little odd, because it
- Means I have to cover more possible inconsistencies, i.e. synchronize the keychain somehow wit the shared web credentials (what if I have credentials in the keychain as well as the shared web credentials, but they're different?)
- Potentially leaves "garbage" behind in the keychain if my user user uninstalls my app (naturally I hope they won't ever do this, but let's be realistic, some will)
Especially the last point had always bothered me in the past (before shared web credentials and autofill were a thing, or when my app doesn't have an associated domain). Unlike on macOS, the iOS Accounts & Passwords feature (in the Settings app) doesn't list ALL passwords, but only the ones used by Safari (i.e. the shared web credentials), correct? Keychain Access on macOS instead offers a means to view and manage all credentials, even those that aren't synchronized over iCloud.
I understand why the same is not offered on iOS, but it also means that for those passwords that my app saves (locally) to "its" keychain "part" can only be managed if I offer a UI for this in my app. And if the user uninstalls the app before using this, the item will stay in the keychain, at least it was that way when I tried it a couple of years ago.
My main question now is, wouldn't it be easier to disregard the article's advice and only rely on the shared web credentials for password storage? That's the part they can edit in Settings (if ever need be) and also it will reflect any password changes done on the website. I would design my app like this then:
First launch: App starts on the Login screen and offers the username/password via Autofill
User logs in: App saves a simple flag in the shared user defaults indicating the user is logged in.
App gets relaunched, e.g. after a device reboot: The app skips the login screen due to the flag and gets the password and user name from the shared web credentials (assuming the user previously granted it permission, of course)
User explicitly logs out: The app deletes the flag, basically setting everything back to first launch
User deletes the username and password from the shared web credentials (e.g. in the Settings app or with Keychain Access on macOS): The app falls back to the login screen as soon as it detects this (e.g. when attempting a remote request, or after relaunch), regardless of the flag. I think this matches the user intention best (if you delete a password you don't want some apps to hold onto it until you log them out)
This setup would avoid any issues with different items in the keychain and shared web storage and it would immediately propagate updates done in the webpage to the app as well (which is what I'd intent for my app anyways). Is there anything that would keep this app flow from working?
(Note: I asked the same question on the apple developer forums, so if you see that as well don't be confused. I will update any potential answers from there to here and vice versa.)
Edit to address #Aaron's answer:
Thank you so much for the info. Your answer helped me realize I misunderstood something about shared web credentials: I assumed that for an app with associated domain, you can access the credentials without user interaction (after perhaps an initial authorization). Like you can set the checkbox on macOS when an application requests credentials. I now realize this is wrong and on iOS you would always have to verify with the user, thanks.
For completeness sake, I still want to point out some of the other things you said:
You are right, we will eventually use token based authentication, so I will save that in the keychain (probably in addition to the password, see below). I just tried to keep the question simple enough at first.
Our app is like an email client where you update new incoming "mail". The mentioned "login flag" in something like the user defaults would thus just indicate whether the app should behave as if subscribed to an inbox or not. Like in Mail, you wouldn't expect to have to login even after relaunch.
For this reason I will probably eventually save the user's password in the (local) keychain along with a token. If the token expires, I can request a new one without user interaction, that's important in our general site and app design. Only if that request fails I would use the shared web credentials (updating my local copy of the creds in the process).
For what it's worth, the last point you mentioned is probably debatable. On macOS, for example (where you can edit the entire keychain, not just Safari passwords) de facto logs you out of an app. Mail, again, as an example. If the keychain item for an inbox is gone, Mail re-asks that the next time it is launched and tries to access the content (effectively a "kind of" login in a way).
Again, thank you a lot for answering, now I can close an open todo. :) Also thanks to #HamZa for giving out a bounty!
Considering this advice:
Do not use the shared web credentials as your primary storage for secure user credentials. Instead, save the user’s credentials in the keychain, and only use the shared web credentials when you can’t find the login credentials in the keychain.
The main issue here is that the shared web credentials process is a little clunky — it requires user interaction and takes time to resolve the credentials. So if the user has already authenticated with your app you want to avoid showing them the login page at all. You can do this by storing credentials in your app's keychain where you can access them immediately without a network connection or user permission.
This doesn't mean you need to store the user's password in the keychain. Typically you would store something like an OAuth access token in the keychain. The presence of this token means the user is authenticated - and if an API endpoint rejects your token then you can take them back to the login page.
This suggestion:
User logs in: App saves a simple flag in the shared user defaults indicating the user is logged in.
is possibly insecure depending on what you're hiding behind the login page, but typically any content belonging to the user should require a valid token to access, not just a bool in the user defaults.
I think this matches the user intention best (if you delete a password you don't want some apps to hold onto it until you log them out)
I disagree with this; I would not expect an iOS app to log out because I deleted a password from my Safari keychain.
I'm using firebase authentication for my app and I have the users sign up, login, and log out all set up and going. However, I'm a little confused on how to manage the state of the users login status. Currently, if a user is logged into the app, but doesn't use the app for an extended period of time, firebase doesn't recognize them as logged in. I'm looking at the documentation and the approach is a bit unclear.
Should I be storing a FIRAuthCredential every time the user logs in, and then call reauthenticateWithCredential using that credential?
Firebase Auth only requires recent sign-in for sensitive operations like: deleting a user, changing a user's email or password. These are for obvious reasons. You want to make sure it is the same user before making such sensitive changes. Otherwise, the user is considered signed in indefinitely by the Firebase Auth backend (your assumption that "firebase doesn't recognize them as logged in" is not correct). Of course, a developer may also require re-auth before other operations like updating credit card, shipping address, etc. A developer would check the auth_time on the Firebase ID token. Only in such cases would you re-auth. You should never store credentials such as password on the client to avoid prompting the user to reauthenticate. It is needed to protect the user's account.
yes I think that is going to be right approach or second approach you can try is like when a user press login button instead of directly calling Authenticate User put a check in which last login timestamp value will be stored when user login compare timestamp value and then perform selected operation as you want . NOTE - you will be required to check weather user exist or not , but I think first approach will be better as if you had noticed in many Social apps like kik it ask for reauthentication after a long period of time but first it authenticate user instead of displaying home screen it take to reAuthenticate screen
I am creating an application using Appcelerator wherein the user needs to enter the username and password to login. Once logged in, the user can enable TouchID for authentication. After logging out, the user can use the TouchID for authentication and use the application.
My flow is that once the username and password is provided, I store those two information in Keychain using the following module iOS Keychain Module. Then I use ti.touchid to authenticate the fingerprint, if success, then I retrieve the username and password from keychain and then send it over HTTPS web service call and login the user to the application.
My query is that, whether this is an acceptable approach.
I am not an iOS developer nor does any ti or keychain terms mean anything to me at all. That's for a start and to reduce the number of down votes i might get.
In terns of security, I would suggest that you imagine obtaining that particular user's phone where you know you have some authentication credentials stored. Let's say I am a user of your app, already logged-in and have my credentials saved somewhere on my device, and you obtain this phone by stealing it from me.
Now, will you be able to access my account in anyway? Will a hacker with access to the physical phone be able to retrieve any information stored in your Keychain storage?
If so, If you can think of anyway to do so, then your approach is not valid.
I understand you want to save users sometime by making sure they can login with just their fingerprint, which is a valid reason to think of such an approach, but you will have to think everything in terms of reverse engineering.
Additional recommendations would be using an on-the-fly hash to store information in the Keychain and making sure to check that before restoring the same. For example, user credentials saved on "home wifi" can be verified with your fingerprint only "at home" on the same wifi network where the same will be invalid on a different network.
i.e)
(keychainItem.x = y) is TRUE ONLY IF (something else)
where this (something else) is something that will prevent hackers from accessing the Keychain even if they have access to the device itself.
I do this myself when programming web applications with stored cookies. I for example use a stored cookie ONLY IF it is being accessed from the same IP it was saved from. Anytime that IP address changes, user will have to re-authenticate even if the cookie values are correct.
Hope this helps.
This is probably a repeat. However, the other answers haven't helped me out. So, here goes.
I'm working on an application and we with need to add 'users' to it. We'll be giving the option for people to sign in with Facebook, Twitter and LinkedIn. I've worked with these APIs before, however never combined them globally.
How can I maintain and manage these users that will use different services to log in. I'm confused as to how they would be stored in a database, would I need to have a different table for each different social service or is there a way to implement a table that will house all users in one place.
From what I understand, you're asking how to manage, store, verify users that will be logging in your application through different social services.
This is how we've implemented it through the various projects we've worked with. From the list of services you've provided we've worked only with twitter and facebook, so I can only speak about that.
Setup:
We have a web service that our iOS app communicates with such as when the iOS app needs to make a request call for user login the server would take the user details trying to login and gives back a response where the app would then do whats necessary.
We have a database stored on the server with a users table which is used to verify a user.
That being said, you need to understand whats common between most social services, or to at least know what the property is that is used by these social services to uniquely identify its users. In this case they all use email to identify users.
You'll find that when interfacing your app with these different APIs, they like to use a login session key used for unique logged in sessions.
So on your database you would store whatever details you want to save of the user, but know that you need to store atleast the username, password (encrypted), email (for identification, unique column), and login_session_key.
Just double check that linkedIn does have something like a session key that it creates when a user logs in with that method. Facebook and twitter do. Send at least the 4 main data properties needed (username, password, email, session) to the server You then follow this sort of approach:
New user
If the user that is new tries to login, the server first checks the email provided even exists in the database, if it does not then you sent a response back alerting the user that the user does not exist; your app would then take them to the register screen for example.
If the user is in the registry page, save all the details you want to store of theirs including username, password and email.
Members
If the user logs in the email will exist on the server side, its an existing user so just update the session key that was sent from the app on log in if the password matches, (in some apps these session keys are used through the life cycle of the application being used, with each request sending the same session key and if at any point the session key does not match during app interaction, it can be concluded that the user has logged elsewhere on another device perhaps.
if the password does not matches return the appropriate message.
That's about it really. We're able to store all facebook and twitter users in one table.
I've been looking into OAuth for a while, but haven't implemented it in any of my applications yet. I'm having trouble really understanding the full concept, so I still have a few questions that I haven't found an answer to, so I hope that anyone can help me.
I want a user to be able to start my application (WP8), login to facebook / twitter / microsoft / ... .
When he gets authenticated, I want to actually save this user to my own DB so I can add some user specific stuff like preferences, posts, ... .
What do I need to save in my own DB to specify a user?
Do I need to save the token itself or is this something that will be invalidated after a while? Or do I need to specify the user's name? With other words: What can I use as a unique identifier?
And what happens when a user would authenticate with for example facebook and he deletes his account?
And one more question, would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
I hope my questions are clear enough!
If not, don't hesitate to ask for more information!
Kind regards,
Gert
I assume that you have your own back-end where you authenticate your own users and your WP8 application is just a client.
First, let me distinguish between a user credential and a user profile. User credential is something that validates who the user is, e.g. username/password, facebook user id supplied with a valid auth token. User profile, is what you store in your own database about the user.
You also need to distinguish between a token you use to authenticate the user and the AccessToken Facebook needs to grant you access to user's data.
So... to answer your questions:
What do I need to save in my own DB to specify a user?
Create a record with user data (like preferences, and your unique user ID), and user's login method (e.g. Facebook) and credential (e.g. Facebook's user ID). This is your user's profile.
Do I need to save the token itself or is this something that will be invalidated after a while?
You can also store the Facebook AccessToken here if you've been granted "offline access" privileges by Facebook, but that is used for Facebook's access by you... not by the user's access to your app/back-end. For user's access you could just use a mechanism similar to cookie-based authentication - it's up to you. You could use the AccessToken as a kind of a "cookie", but you would need to always check against Facebook that it's valid.
With other words: What can I use as a unique identifier?
You could treat Facebook's ID as unique (so long as you never allow another account in your user profile DB to link with the same Facebook account)
And what happens when a user would authenticate with for example facebook and he deletes his account?
It's a good idea to have users still create a username/password combination that works with you site and only rely on Facebook login for convenience. In any case, Facebook provides a "Deauthorize Callback URL" when you create an app profile on Facebook. This is called when a user deactivates your app or deletes an account with Facebook. When you receive this call, you could send your user an email when an auth link to setup a different credential so as to not lose access.
would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
Sure, you could do that. Say you'd want to allow a Twitter account as well. You'd need to add a Twitter user ID field to your user profile database.
Here's another tip: create an ASP.NET MVC4 project in Visual Studio - the template includes an example of how to set up a user profile database with OAuth login.
Hope it gives you the high-level overview to investigate further.