I noticed that OAuth 2 in its spec recommends the use of a property expires_in that defines how long the access code is valid.
This seems backwards to me, as the API still needs to calculate the time at which this expires to save it in the database, and the receiver needs to do the same. It seems much more sane to pass the expiry time as a standardised UNIX timestamp, which both the API and the application can save in their db to check for expiry times.
Since nobody seems to have an answer to this I'll add my assumption as an answer:
Server and device times will not always match. Which is why a duration is the more logical way to go.
Consider a user disabling time-syncing with servers and manually setting his/her time 1 week in the past. The tokens received from oAuth servers don't take this into account, they just set an expiry date and send a timestamp to the device assuming the device's clock is in sync AND it will convert the timestamp to the correct device timezone.
By sending a duration these "misunderstandings" can be bypassed.
Related
i'm developing application with in app subscriptions (monthly, yearly). When i'm getting the receipt from apple with response (i'm validating receipt with apple server, i know this is not a good idea, but still), i want to check the expiration date of the subscription. Here's the checking part.
NSDate *currentDate = [NSDate date];
NSDate *expireDate = receipt[#"expires_date"];
NSComparisonResult result = [currentDate compare:expireDate];
BOOL subscribed = (result != NSOrderedDescending);
But if the device time is wrong(the user changed the time of the device) how can i be sure that subscription is still active ? Maybe i should request the current time from the server ?
I suggest reading up a little more about Apple's receipt verification and how most effectively validate In-App Purchases.
To your question: In short, yes. Requesting the current time from a server will give you the current time independent from the users device. This will always be the most reliable way to retrieve the current time.
A little more detail...
What you need to do is read the receipt url as data then base 64 encode it from the data. There is a similar post to this question which will be helpful in understanding this process.
Ultimately you need to handle this sensitive data as securely as you can - this process will allow you to retrieve the best kept "safe" expiration date (receipt) for your IAP.
Read this post to help point you in the right direction.
In regard to checking the "correct time" there are a few approaches you can take here.
Approach 1
Get the correct time from an API. Here is an API you could use to get the world time. You could also use AWS to get the current time.
Approach 2
This response goes into a simple way to monitor device clock changes to make sure / listen for the user changing the time. By monitoring for any large time changes you can decide whether the user has changed the clock maliciously or not.
Approach 1 will deliver (of course) an independent time for you to compare that should always be the true current time, where as 2 is a way that you can monitor the device's clock.
In iOS, as per the official docs, there's no method to set a timeout duration for the phone number verification code (or even know the default one). Could some Firebaser clarify why is it so? What's the default timeout duration? If possible, how could one set it in iOS?
On the other hand, in Android, all is good: https://firebase.google.com/docs/auth/android/phone-auth#send-a-verification-code-to-the-users-phone
FirebaseUI takes a different approach where they show a timer before they allow the user to resend the code (they use 15 seconds). This is a better approach as even if the expiration is provided, it will be inaccurate due to various latencies in the flow and the value is likely to change as Firebase Auth has the right to change that for security reasons. Otherwise, it could be used for brute force attacks.
The onCodeAutoRetrievalTimeOut timeout for Android is unrelated. It is the timeout for code auto retrieval before you ask the user to provide the code and not the timeout for code entry. Auto retrieval is an android feature only.
I am coding in Xcode 6.1.1 with objective-c.
In my app it is critical that I use the correct time.
I only want the app to use the time of the device when the time is synced with the servers.
If an user is somehow using his/her own "weird" time the app should detect that and tell the user to switch back to use the app.
I know there is NSSystemClockDidChangeNotification, but that only gives back when the time is changed. It does not give back what the change was and if the user switched to "custom" time or synced back to an NTP server.
Question: How do I detect if an user is connected to an NTP server or not?
Maddy is right that you can't specifically find this out from iOS.
However, in the past I've delivered a client for a premium subscription service that had a similar need to know if the user was messing with time. In particular we needed to verify this when there was no network available, in order to prevent the user from accessing premium content after their subscription had lapsed. The very simple mechanism we used was as follows (IIRC):
every time the app launches or comes in from the background, record the current time (eg: in NSUserDefaults)
compare the current time to the last recorded time--if the current time is earlier than the last recorded time, force the user to go online and sign in to the service.
I don't claim it is 100% foolproof, but for our purposes we felt it was good enough to prevent users from trying to circumvent time-based restrictions on accessing premium content.
if i set say 1 min expiration but due to large file if it can not be downloaded within expiry time, will download will break/cancelled as time expired.
i need to keep the mim expiration time due to some reason.
Thanks for reply.
The expiration time is only tested when S3 initially receives the request.
The amount of time the download requires is not important, because the "expiration" time refers to how long the signed url can be used to begin downloading.
The exception to this is not really an exception, though it might appear to be if you didn't understanf what was happening. HTTP and S3 allow a client to specify a range of bytes to download. It is probably not common, but it is possible, for a download to be done in discrete chunks. If the client is attempting this, then all of the pieces have to be requested before the signed url expires, since the time each request is made is validated against the expiration time of the signed url.
As I understand for the moment, the location and time sensitive passes in Passbook only support time and/or location based notifications. So at the correct time and location, the user will get a notification for the pass.
I was wondering if these properties also can be used to change the pass. For example, if you are in some specific store, the coupon provides a 50% reduction instead of a 20% reduction. If it is not possible to do this locally on the iOS device, is it possible to send a request to the server based on location and/or date to achieve the same thing?
Sorry to be the bearer of bad news, but it's not possible to accomplish this.
Firstly, the data within the pass is fixed at any point in time. As you've said, it can be fixed to a list of locations and/or a date.
Secondly, the pass cannot communicate with a server except to request an update in response to a push notification. This means you will never know where a pass is.
The only option way to achieve something like this would be to generate passes using an app that is location aware, but I don't think this is what you're after.
You can send a push update to a Pass at a specific time. This way you can (for example) convert a 10%-off coupon to 20%-off on Fridays (and then switch it back after Friday).
After a user has initially 'Added' your Pass promotion into their Passbook you can update it at any time without requiring the user to 're-approve' your update.
Your server does not know when a Passbook user has triggered a location alert - otherwise you could track their movements via Passbook. Apple does not want their customer's security to be compromised in this way.
However, you could issue a coupon that is normally 20%-off (for most stores, or online) but that the location alert for a specific store said 'Get 50% Off at this store'. When the customer comes in to have their Pass scanned & activated, your server will then know the customer's location and can apply the 50% reduction.