Does anyone have any tips migrating from the old iOS FB SDK (the one hosted on their GitHub account) to their .framework (package-based installer) one? I'm having issues getting the existing auth token and expiration date objects to validate against the new FBSession object.
Here's the situation:
In the old SDK/technique, the Facebook iOS SDK required you to save things like the auth. token and expiration date manually through your own storage mechanisms. In the new framework based SDK they now handle this for you, but in order to migrate users (i.e. not have them re-login) I need to provide this information to the new SDK.
It winds up being that Facebook is storing the K-Vs in NSUserDefaults and they even tell you the root key name as well as all the keys for the nested K-Vs of the dictionary they use to store this information.
Their token class FBSessionTokenCachingStrategy even has a class method to verify if an NSDictionary validates to a proper dictionary that establishes a usable Facebook session
+ (BOOL)isValidTokenInformation:(NSDictionary*)tokenInformation;
So I've taken my preexisting auth. token and expiration, put them in a new dictionary, stored it in the proper key'ed location and synchronized NSUserDefaults.
So far so good right? Well once I initialize a FBSession object via
- (id)initWithAppID:(NSString*)appID
permissions:(NSArray*)permissions
urlSchemeSuffix:(NSString*)urlSchemeSuffix
tokenCacheStrategy:(FBSessionTokenCachingStrategy*)tokenCachingStrategy;
The whole key is removed from NSUserDefaults and the session object's state property is in the state of FBSessionStateCreated (i.e. no preexisting state) vs what it should be FBSessionStateCreatedTokenLoaded (i.e. it knows it has the locally saved properties and is ready to be checked online).
Why is it being removed? It validated against the class method.
Thanks
It turns out that the local storage object for newer Facebook SDK also preserves the permissions list related to the token. This wasn't required before so while I didn't have it saved locally, my permissions list did not change. So what I did was also save the permissions list into the new storage object (totaling 3 keys: auth. token, expiration date, and the permissions list).
Once I had done this, creating/initializing the FBSession object did not remove my locally stored object and upon invoking openWithCompletionHandler: it established the expected session state to FBSessionStateOpen.
Related
I want to create a new iOS app.
and for this app I have some security questions
Example
The first start the user log in with username and password. When the log in is correct The user receive a api code. Just This code Will be stored in the app
So every time they use a make a request to the side like calling for the use a list I don't send the username and password I will send the api code for authentication.
Like this
https://example.com/api/{APICODE}/getUserList
The answer will be json
So my Questions are
- how to securely store the api code in the app
- is there a better way to make the requests
- I will store the requested data in the app, what is the best way, SQLite or plain files with json
The reason is That the app works without Internet
Thanks for help
Save secured data in the Keychain. For other you may use UserDefaults, files, SQLite DBs, CoreData
I am using a Swagger generated Swift Client which uses NSURLCredentials to authenticate with a server. I am using persistence type .Permanent
My app communicates with the server in the background and works fine, except when I lock the phone (I see 401 errors in the log). I believe that NSURLCredential is not able to access the keychain when the phone is locked.
I came across some posts which talk about enabling keychain access using kSecAttrAccessibleAfterFirstUnlock. I haven't been able to figure out how to do this with NSURLCredential. Does anyone know if and how this can be configured?
Yes, that's exactly what is happening, in all likelihood. You have a couple of options:
Delete the underlying keychain item and recreate it, specifying that it should be accessible when the device is unlocked. You don't need to use NSURLCredential at all with that approach. Just create an internet password item using Keychain Services APIs and the credential store should pick it up automatically.
Keep the credential data in memory, and implement the URLSession:task:didReceiveChallenge:completionHandler: delegate method in your session delegate (or the equivalent method for NSURLConnection if you're using that API) to provide the credential when asked.
I am 100% new to AWS and to the AWS iOS SDK.
I am using The Standard AWS Code Example. to initialize the Cognito credentials provider. I of course am changing #"COGNITO_IDENTITY_POOL"].
I have noticed that when I do this the first time for a device that NSString *cognitoId = credentialsProvider.identityId; is nil. Is this to be expected? if so at what time is the property available?
Also is my understanding correct that the SDK saves this Cognito ID in the devices key chain? Thus this identity will not change for the device while ever the user backs up his operating system. If for example he wipes his device and freshly installs iOS then a new ID (same app same Congnito pool) will be generated? If however he just deletes my App but later installs it again (no change to iOS), then if I use the same Cognito pool he will be recognized as an existing member with the same ID?
"credentialsProvider.identityId" is null the first time you use the SDK, until it gets refreshed. Once you get an identity from the service, it will get stored in the keychain and the device will always reuse the same one (unless, as you said, the user clears the keychain or wipes the device).
Albert
I am looking for a way to load simperium without having to present the login view after the first time the user enters his info.
This is what I get if I dont log in after the first time:
Simperium error: bucket list not loaded. Ensure Simperium is started
before any objects are fetched.
This is what I use to init Simperium:
self.simperium = [[Simperium alloc] initWithRootViewController:
_window.rootViewController];
thanks
Consider using OAuth.
OAuth is a system where the user can provide their credentials for a popular service like Google, Twitter, Facebook or other open ID providers.
Rather than caching the credentials on the device, which would be insecure, since getting access to these would give the user access to a large number of systems, OAuth gets the main authentication service to provide a token.
This token gets stored on the device and can be used to login automatically the next time.
The drawback is that it can be quite tricky to set up the first time, since there's quite a lot of complexity going on, not to mention that the standard is quite new so there was some evolution in the specification.
Simperium just needs user credentials to get started (the app id and username/token). The login view is a convenience to get those credentials for you, if you can already obtain them using some other means (like using HTTP auth API: https://simperium.com/docs/reference/http/#auth) then you can directly supply those without using the login view. See methods in https://github.com/Simperium/simperium-ios/blob/develop/Simperium/SPAuthenticator.m
How to correct initialize FBSessionTokenCachingStrategy?
I have: facebook-ios-sdk (not new, but 3.0).
Also, i have an iOS-project, thtat must run under iOS 5.*
And i have a trouble:
How to correct initialize session, if it must be reopen (not open)?
I have a token from last session and i want to login with this token.
But for this i need to create a FBSessionTokenCachingStrategy instance.
How to do this?
Thanks for help!
As i said before, i need this to create session and open it.
Let's see, what i want:
load TOKEN from my server. (and misc info about user).
create session
open session
NOTE:
It can be, that FBSessionTokenCachingStrategy instance was not saved on device.
And i need to create it.
And this is my algorithm: (code will be posted later)
load TOKEN, expirationDate, userID from my server.
create FBSessionTokenCachingStrategy instance manually, input in it's settings dictionary all fields, loaded in first step and(!) PERMISSIONS (it predefined in my app).
init session.
open session.
Success!