10

In my current application,i have to let user to login from different iOS devices to their account. Currently i'm doing user authentication from a token value. but in order to support multiple device login i have to find another way for doing this.

Thus, I thought of saving devices uuid along with token for authentication + security. Then, I come to know I can't use device's uuid, instead I have to use identifierForVendor which may or may not provide user or device information always.

So, can anybody suggest the better and proper way of achieving this multiple device login feature for same user account in ios ?

Uniruddh
  • 4,427
  • 3
  • 52
  • 86

3 Answers3

9

As you already know this using the device's UUID isn't allowed, however, you can generate your own UUID and store it on the devices' UserDefaults.

using the identifierForVendor isn't 100% reliable, as it only works on iOS6 and above, and users have the ability to opt-out of giving it to you, which makes it a bad choice.

Here's some code I copied of the internets sometime ago and still use it till today, will try to find the source and update my answer in a bit. EDIT: Source

This will generate and store a UUID for you in UserDefaults:

- (NSString *)createUUID
{
  CFUUIDRef theUUID = CFUUIDCreate(NULL);
  CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  CFRelease(theUUID);
  [[NSUserDefaults standardUserDefaults] setObject:(__bridge NSString *)string forKey:@"UUID"];
  [[NSUSerDefaults standardUserDefaults] synchronize];
  return (__bridge NSString *)string;
}

And whenever you need to read the generated UUID:

- (NSString*)UUID
{
    return [[NSUserDefaults standardUserDefaults] ObjectForKey:@"UUID"];
}

Now you have the choice to append your own user's ID to that too so you'll be able to know what UUID is linked to which user..

This is just a rough sketch of how it should work

Community
  • 1
  • 1
Mostafa Berg
  • 3,211
  • 22
  • 36
  • i will assume that if a user reinstalls the app a new UUID will be created? – rup3rt Mar 29 '14 at 08:53
  • That doesn't sound useful. How would someone like the credit card company trace fraudulent activity back to the device if the id can change? – Sinaesthetic Aug 05 '14 at 22:13
  • 1
    @Sinaesthetic That's not the scope of this solution, I'm not sure what you mean but there are a billion ways to track the activity on the phone, it's just not opened to 3rd party developers, i guess it's just accessible via apple, or NSA ;), but if you mean the device's UDID, that never changes ! – Mostafa Berg Aug 06 '14 at 23:12
  • Financial applications need to be able to uniquely identify the device and send that information to the processor (e.g. MasterCard). Apple makes the UUID inaccesible and the ApplicationID alternative that they provide can change if the user uninstalls and reinstalls the app just the same as the app generating its own code-- so it's not really identifying any device is it? I'm not being combative, I'm just trying to solve this problem as well. – Sinaesthetic Aug 07 '14 at 00:29
  • @Sinaesthetic I understand your point, but they don't only rely on device info as the only way to identify the user, remember they have to register the device upon install, which links the current generated UDID to their username/account, if the user reinstalls the app, they still have to register again and link the newly generated UDID to the new account, and in their internal logs they will still have all transaction history with a all UDID's that this client has ever used.. hope that answers your question ? – Mostafa Berg Aug 07 '14 at 14:10
  • Ok imagine the scenario:A single device that can support multiple users via their username/password. I am MasterCard. I have a transaction that appears to be fraudulent. I need to know what user with what device (ie lane) on which this transaction was performed. With what you're saying, I am able to see that UserA did the transaction on device A23423 which is also known as device A99999 and AB3243 (it was reinstalled twice). What does the generated device ID mean to me? How would I be able to prove what physical device the transaction took place on? What's to stop anyone from spoofing that ID? – Sinaesthetic Aug 10 '14 at 23:39
  • In other words, how do I prove that Alex performed a transaction on Jake's phone that was given to him by John? – Sinaesthetic Aug 10 '14 at 23:40
  • The device isn't `also known as A99999 `, it *was* known as thos A99999, the device will have one and only one current UDID at a time. your scenario isn't making sense to me and actually has nothing to do with UDIDs – Mostafa Berg Aug 11 '14 at 12:35
  • Regarding`identifierForVendor`, the answer says, "users have the ability to opt-out of giving it to you." I don't believe that is correct. `identifierForVendor` is always valid. Apple docs don't say otherwise. See [https://stackoverflow.com/a/12698912](https://stackoverflow.com/a/12698912) – Jeff Aug 19 '21 at 06:46
2

First of all, Apple developer guidelines prohibit/ discourage use of IDFA for tracking the user for the purpose of displaying targeted advertisements (and a few other things). The guidelines clearly allow the developer to use the IDFA for identifying the device for security purposes. Quoting the apple guidelines

advertisingTrackingEnabled

A Boolean value that indicates whether the user has limited ad tracking. (read-only)

@property(nonatomic, readonly, getter=isAdvertisingTrackingEnabled) BOOL advertisingTrackingEnabled

Discussion

Check the value of this property before performing any advertising tracking. If the value is NO, use the advertising identifier only for the following purposes: frequency capping, conversion events, estimating the number of unique users, security and fraud detection, and debugging.

You can use IDFA of the device for the purpose of multiple device logins. The flow would be somewhat like this:

  1. User logs in to the server using device A, Server sends back a token which is stored on the device in NSUserDefaults. The app also stores the IDFA on the device in NSUserDefaults

  2. This token will be used for creating an encrypted string which would contain the IDFA. (encrypt the IDFA using the token) The encrypted value would be passed to the server in each request along with the original IDFA.

  3. The server would then use the IDFA and the token associated with it (the server would of course be storing the IDFA's corresponding to each token) to get the encrypted value of the IDFA and match it with the encrypted value received in the request. The purpose of doing this is to ensure that no one can hack into your server as the token would not be visible to anyone but the app (You can even store the token in an encrypted format so as to increase the level of security).

  4. Whenever a request is sent to the server, the value of IDFA stored on the device in NSUserDefaults would be compared with the current IDFA.

  5. In case there is a mismatch, the current IDFA would be first updated to the server and then after getting the confirmation of successful update the app would replace the IDFA stored on the device in NSUserDefaults with the current one (and business then runs as usual).

Alternatively you can avoid step 3,4 and storing IDFA on the device in NSUserDefaults but in that can the user would have to re-login on to the server on resetting the IDFA.

Just confirming ,the mapping of token to IDFA would be many to one.

Hope this helps, comment in case anything not clear/ not satisfying the use case.

Community
  • 1
  • 1
Akshat Singhal
  • 1,801
  • 19
  • 20
0

you should use the standard ways of creating a UUID. Apple does not want you tracking devices.

 To create a unique identifier specific to your app, you can call the CFUUIDCreate function to
 create a UUID, and write it to the defaults database using the NSUserDefaults class. (Source)

If you want to use a library for this instead of rolling your own, you should use this excellent library like this :

CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
NSString *uuidString = (NSString *)CFUUIDCreateString(NULL,uuidRef);
CFRelease(uuidRef);
Purva
  • 1,291
  • 2
  • 15
  • 30