Storing authentication tokens on iOS - NSUserDefaults vs Keychain?
Which is the place I should be storing tokens for when the user logins in to a service? I'm not saving passwords (obviously where I'd use the Keychain) but just the token. A lot of places say just use NSUserDefaults but some people on StackOverflow seem really keen on the Keychain.
Is NSUserDefaults fine?
Solution 1:
I would highly recommend you use the keychain - it's exactly what Facebook do for storing their session tokens.
NSUserDefaults
is not secure or encrypted - it can be easily opened and read, both on device and when synced to a Mac. So whilst user defaults is a good place for things like preferences and config info, it's not a good place for anything sensitive, like passwords.
Session tokens should almost always treated the same as passwords, so you should store them securely in the keychain, where they'll be encrypted. Apple have some sample code (GenericKeychain) that shows a basic implementation, and you'll find other examples by searching StackOverflow. Hope that's helped you out.
Solution 2:
NSUserDefaults can be used without any problems (for tokens!). Please check documentation https://developer.apple.com/documentation/security/keychain_services
Keychain Services are invented to “secrets” that the user explicitly cares about, i.e. passwords, private keys or even secure notes, i.e. clear credentials. But access tokens are temporary hashes generated after user entered password and have limited time. And even if stolen, the malefactor cannot completely stole the account - the owner can login on another device and previous access token will be reset. So, formally there is no forbiddance to store access tokens in UserDefaults.
The data from UserDefaults can be stolen only if the device is stolen itself, but I think the security level of the content is much lower than the physical device itself. I think user would not worry about the token in that case, but about the device.
However, it’s a good practice to store it in Keychain, but it’s just an excessive (!) usage of security and usually recommended by random users in the Internet and it’s not required by Apple. There is no documentation by Apple there they say that tokens must be stored in Keychain (if you can find one, then please comment one below).
So, the answer is - you can use both. However, if you app is operating with content that costs a lot in contrast to stolen iPhone, then it's better to use Keychain, but it's just a recommendation.
Solution 3:
All sensitive data should be stored in the keychain.
UserDefaults
is for small pieces of data like user preferences.