Queries on public classes fail while user has invalid session - ios

This is questionable behavior on Parse's part, but I need to find a workaround. I have discovered that once a user's session is invalidated, all future requests will fail until the session is valid again, including queries for data that is available to query publicly - without logging in.
This is biting me because my Sign Up screen requires the user select from some PFObjects that are queried from a publicly accessible class. I show a list of options, they tap on one, then I set that object on the new user object created when they tap Sign Up. The problem arises when their session is invalidated. I present the log in or sign up screen, but if they want to sign up they cannot, because the query for the information required in sign up fails with error Error Domain=Parse Code=209 "invalid session token" (despite the fact the user doesn't need to have an active session to access the data).
Therefore it is impossible for the user to create a new account after they logged into an account and said account had its session invalidated. This will occur in a few situations: the account session actually expires, the user logged in with Facebook and its session expired, or the user was deleted altogether (perhaps because they posted something inappropriate). In all cases I get the 209 invalid session error, and I need to support the ability to sign up at that time - especially the latter because it's impossible for them to sign into their account that was deleted.
What can be done in this situation?

You can force log out the user when you detect their session is invalid. This request will still report the 209 error, despite the fact it actually succeeds in logging the user out. Once the user is logged out you can query on the public classes.
func sessionInvalidated() {
//force log out, otherwise can't fetch info in sign up screen with an invalid session
PFUser.logOutInBackgroundWithBlock({ (error: NSError?) -> Void in
//still will get 209 invalid session, user is still logged out in this case, ignore
if error == nil || error!.code == 209 {
self.showWelcomeScreen()
}
})
}
Source: https://github.com/ParsePlatform/Parse-SDK-iOS-OSX/issues/671

Related

Can't remove currentUser.uid from device

Auth.auth().currentUser?.uid
This call returns a uid no matter if the user exists or not as an authenticated user. I have tried manually removing the user from the Authentication section of the Firebase web portal, and I have tried removing the user in Swift via:
Auth.auth().currentUser?.delete(completion: { (error) in
print(error)
})
I then receive this error:
Optional(Error Domain=FIRAuthErrorDomain Code=17011 "There is no user record corresponding to this identifier. The user may have been deleted." UserInfo={NSLocalizedDescription=There is no user record corresponding to this identifier. The user may have been deleted., error_name=ERROR_USER_NOT_FOUND})
The uid persists even after deleting the app and rebuilding it on the device.
I just need to get the uid cleared when I remove a user, and for the life of me I can't make it happen. I really need to be able to test brand new devices/accounts using the app for the first time, which isn't possible with this persisting uid. What step am I missing here?
If it helps, I'm doing this with anonymous user accounts. Ideally I would be able to register a new anonymous account and see it appear each time I delete it from the device.
This may be an Firebase Auth iOS bug. I have filed a bug with Firebase Auth. What you can do, is catch that error (when you try to delete the user) and on detection signOut the user so they are not persisted anymore.
If you're using anonymous user accounts, you're going to get an automatically generated UID that is tied to the current installed instance of your app. You can see in the docs:
let isAnonymous = user!.isAnonymous // true
let uid = user!.uid
AFAIK, you can't log out/delete an anonymous user, because there is no authentication context to remove. Can you solve your issue by checking for both isAnonymous and uid at the same time, instead of trying to rely on the existence of uid?

Proper way to handle Swift Firebase User Login state

I've been looking around the web and trying to find out how to handle the user state of a logged in Firebase user where the following occurs:
User is already logged into the app.
Admin disable/delete the user from the Firebase Console.
User is still inside the app (although the account has been disabled/deleted on the Firebase Console).
After more than an hour, user is still inside the app. (Firebase ID token should have expired and addStateDidChangeListener() should've been called).
Currently, unless i call getIDTokenForcingRefresh() and signout() the user if the return error is due to disable/delete user. The user will still be logged in.
In summary, I've the following questions:
If a user is logged into the app, the user will remain logged in unless a signout() is called. It doesn't matter if the user account is disabled or deleted?
The Firebase ID token 1hour expiry only triggers the addStateDidChangeListener() but I'll have to handle what to do inside the handler?
What is the difference if I use reauthenticateWithCredential() to check for update state of the user?
Thanks for any clarification and help in advance! =)
I don't know if I will answer all of you questions but I can give you some info from my experience with Firebase.
As far as I know, if user gets deleted or disabled he will still be logged in app until token expires. Anytime you will try to manipulate with some data in Firebase (read, write, whatever) after the user has been disabled / deleted you will get an error in the result block. That is when you should check what kind of error it is and perform some actions. In this case, if error matched deleted / disabled user you should log him out and take to login screen. Here is a list of all errors.
reauthenticateWithCredential() is a way to do that but you will get the same error when reading other data from Firebase. So if a user is disabled, calling reauthenticateWithCredential() will return an error with code FIRAuthErrorCodeUserDisabled. That is how you detect that user was disabled.

How to block a specific user from your app?

I have an app that allows users to only log in through Facebook. The backend is Parse. I have many fake users creating accounts and screwing up my app, posting inappropriate things. Is there a way to block a list of Facebook accounts from logging in/using my app? I have the list of their Facebook IDs, but I am not sure how to block them by writing a Cloud Code.
Thank you in advance!
Simply add a new boolean column to your User table to indicate if this user is blocked/blacklisted. Every time a Facebook user gets a new session, their authData field needs to be updated. So you can use thebeforeSave trigger on Cloud to check if a user is blacklisted and return an error which prevents them from getting a new token and logging in at all.
Now to block a user, find their session record in the Session table and delete it which invalidates their token and logs them out. Then simply set their blocked field to true. They should not be able to log in to your app any more.

Managing iOS app UI state based on user being logged in or not

I have an app which presents a login screen on first launch. When the user logs in, I give them an option to remain logged in. This establishes a session with an expiry on my server. What's the most appropriate way to do the following things:
Store whether the user is logged in or not.
Present the user with a login or logout option on application launch based on the validity
of their session.
End their current session if they choose to logout (or if their session is expired).
I'm guessing this is a common design pattern and there should be tried and tested ways to do this but I seem to be using the wrong terms to search because I haven't found a satisfactory answer.
Some ideas:
I would suggest you store your sensitive session information in the application's KeyChain. I wouldn't store here the state of wether the user is logged in or not, just store that in memory. Your webservice should be able to return an error when the session ceases to exist, or if the user has logged out.
If the backend determines the session's validity, then you should have a RESTful call where you can pass the session information, returning whether the session is still valid.
Again, if they choose to logout, then you could perform another call to your backend passing the session information.
For the Keychain, use the KeychainItemWrapper from Apple's examples.

why is jsessionid cookie allowing user to access member content even though credentials are wrong?

So, I think it is because of the JSESSIONID cookie that is causing the problem, but not too sure, here goes.
Basically, users are required to enter a special token when logging in. But somehow users are able to access the private/member pages even without entering that token.
So user enters credentials minus the token, errors pops up, user ignores it. Of course since there is that error, user is not directed to the members pages. BUT user can manually type in the specific member page and get access to it.
user goes to mysite.com/home
user enter username/password, no token --> error pops up
user ignore the error pop up, enters mysite.com/member/home manually and get access to it
I believe it is the jsessionid, once i remove that cookie the access to the members page are gone as well.
Any ideas?
Actually, it is not jsessionid that is causing the issue, but some weird servlet doing weird stuff...

Resources