In App Purchase backend architecture: user accounts and protecting the app from "borrowed account" downloads

620 views Asked by At

I am a frontend developer and I'm about to start writing my first backend (using AWS so hopefully it won't be a disaster). I need some guidance, can be a link to an appropriate topic on SO or a tutorial or whatever - I've searched for a long time but I probably don't know HOW to search for the problem I need to solve.

Keeping things simple: my client sells books. To complement these books, we are currently developing an app. Different parts of this app will correspond to different books, although the app has its value on its own, too (i.e. you don't have to own a book to use the app). The idea is that if a user owns a book, he is to be allowed to download the corresponding part of the app from the AppStore for free. It he doesn't, he has to use IAP to buy this content for some amount of money.

I've come up with the following simple solution:

  • we're maintaining a database with all sold books' ids
  • we allow the users to register and input the id(s) of the book(s) they own
  • we check these ids against our database as well as check if no other user has input the id(s) previously
  • if the id(s) is(are) OK, we allow the user to download the content corresponding to the owned book(s).

The user is able to download the content from multiple devices (e.g. his iPad, his iPhone, his kid's iPhone...) if he logs in to his account on these devices.

However, I would like to prevent situations when the user gives his account to a friend, who then logs in to this account on his device and downloads the content, then logs out and uses the app, even though he hasn't bought anything and he doesn't own the book(s).

My ideas:

  • The user must be logged in to verify he is entitled to use the content, even if the content is already on his phone (downloaded previously). The user can only be logged in to one device at the same time (upon logging to another device, he'll get logged out from the first device). SERIOUS DISADVANTAGE: The user can only use the app when connected to the Internet, even though he might have all the content downloaded.

  • By performing inapp purchase or buying a book, the user becomes entitled to, say, 3 downloads. SERIOUS DISADVANTAGE: what if the user removes the app and wants then to reinstall it? Redownloading purchased parts will count as one download as there is no reliable means to check if the device is the same as before, at least not for iOS - there's something called vendorId, but it's proved unreliable – e.g. changing on system update.

  • offer the same content for the lowest possible price (instead of for free) for book owners and for a regular price for others. This way I'll delegate all the checking to Apple (via user's iCloud account), since unlocking content will always require using IAP and once the purchase is made, Apple will keep track of everything.

  • other ways to do it? Please help.

There's also one additional thing to take into consideration - we'd like to have a possibility of making "classroom accounts" - multiple devices can log in to the same account and download the content. The client would decide how many devices are allowed and put in this number of downloads to the database.

2

There are 2 answers

1
Jim W On

How can you distinguish between:

The user is able to download the content from multiple devices (e.g. his iPad, his iPhone, his kid's iPhone...) if he logs in to his account on these devices.

and:

However, I would like to prevent situations when the user gives his account to a friend, who then logs in to this account on his device and downloads the content, then logs out and uses the app, even though he hasn't bought anything and he doesn't own the book(s).

Maybe it is technically possible, but I would question whether it is worth doing. It's more likely that restrictive licensing is going to inconvenience your good customers, than prevent piracy. Not to mention the technical challenge with doing so.

0
Frnka On

Having these issues so thought I would address the question.

A useful tool to some of these kinds of problem within the app is a powerful Sign Out button. If on Sign-Out you unauthenticate the user through your database, wipe User Defaults, and even clear the database of downloaded material, you will at least catch users trying to use multiple accounts on the same device. Typical users don't ever sign out of the app.

Then you can take advantage of UserDefaults/LocalVariables to hold purchases or premium info for offline capability, and then reference AWS when needed. The AWS authentication listeners will carry a lot of the load if you set them up well, where you can be logged in even after uninstalling and reinstalling the app.

Another piece as you mention in your first idea is to make sure the user is only logged in to one device at a time. Snapchat does it, so it's fine UX, right?

For classroom accounts, you would have to set up more advanced monitoring to make sure they aren't using them on outside machines. It could help if you have access to the MAC and IP addresses of all the registered machines.