StoreKit - format of clientToken for requestPersonalizationToken? - ios

In the sparse Apple StoreKit Docs it mentions using a clientToken to request a personalizationToken from a device via requestPersonalizationToken.
There is no accompanying documentation to describe what this token should be. I had assumed that it should take the form of a developer JWT token but that does not appear to work, giving the error SKErrorDomain code 8 with a nil token response.
I know that the token works for a regular call to the Music API and so assume it is of the correct format for a developerToken.
I am aware that Apple are not giving out tokens via requestUserTokenForDeveloperToken until later in the year but assumed that requestPersonalizationToken was the current (although already deprecated) method until iOS 11 is released.

Apple Music sample code is using "requestPersonalizationToken forClientToken" for pre iOS 11 devices. The sample is passing MusicKit developerToken in JWT form for client token.

For any others that hit this thread.
Yes, the token is the same format. Apple have recently pushed an update out that resolves the issues that I was encountering. The exact same code now successfully retrieves a UserToken.

Related

Fitbit oauth2 public API stopped working. Giving error - Sorry Its not you.. Its us

Few months back I prepared a demo on Fitbit oauth2 public APIs in which I used to log in with a particular user and get his activities. It was working fine. But recently, I opened the demo and tried to log in with the same user but it is not getting logged in and repeatedly giving me this error.
I tried to change the client secret key of this demo app which I registered on Fitbit but nothing happened. I am stuck here.
There is problem with the format of Callback URL. I think Fitbit has recently changed it.
Earlier, the format of Callback URL was "demoapp://" but now
it will be "demoapp://something"
Please refer to my answer on other question.
Setting up Fitbit api in xcode Swift

Sign in via Twitter (iOS)

I am developing an iOS app and want to implement native sign in via Twitter. I am using an example I found here that includes 2 steps, request token and access token. For the second step I use my twitter ACAccount (account.framework) and my app consumer_key and consumer_secret, and finally obtain an oath_token and oath_token_secret.
The problem is that when I try to fetch data with that token in my app API I get invalid token.
I think a step might be missing here or something. I look at every post related to sign in via Twitter and couldn't solve this...
Thanks everyone
This is the example I based my code
https://github.com/seancook/TWReverseAuthExample
I did almost everything the same, I am using ARC

YouTube API broken by Google. 'Authentication with Google failed. Reason: NoLinkedYouTubeAccount'

** UPDATE **
It truly seems that Google has just screwed every single person on the planet by absolutely requiring user interaction to upload a video. Of course I know, they are free. Exactly what I warned the client years ago about, so I don't need to be reminded. Thank You.
So I would like to try to take this in a different direction and just find a loophole and a workaround to still keep doing what we are doing in spite of Google's complete lack of support or caring in any way about the developers and what they have to deal with.
It would be different if you can actually call a phone number and talk to a human being about YouTube Partner access, but you can more quickly get access to the Illuminati.
OAuth 2.0 is now the only supported authentication method period. It does require user interaction.
But what about that token? Does anybody know how long the token lasts?
If I can obtain a token just once using user interaction and place it in the database, I can automate possibly hundreds or thousands of interactions afterwards.
In other words, I'm trying to turn the user interaction into a speed bump instead of a concrete wall.
If anybody has any examples of obtaining that token, caching it, and using it afterwards, that would be a godsend to me right now.
Thanks for the comments and the help. I'm not surprised that the YouTube Developers Forum just folded and said to come here instead :)
It seems that Google has completely pulled the plug on the existing dashboard.
https://code.google.com/apis/youtube/dashboard/gwt/index.html
That link is now 404'd. Tried from several different browsers on different systems.
Registered under the new Google APIs Console already, but still get the problem.
// Set the authentication URL for this connection object
$authenticationURL= 'https://www.google.com/youtube/accounts/ClientLogin';
// Try to connect to YouTube with the channel credentials passed
try {
$httpClient =
Zend_Gdata_ClientLogin::getHttpClient(
$username = $channelfields['EMAIL_ADDRESS'],
$password = $channelfields['PASSCODE'],
$service = 'youtube',
$client = null,
$source = 'Redacted Data',
$loginToken = $channelfields['CACHED_TOKEN'],
$loginCaptcha = '',
$authenticationURL);
} catch (Zend_Gdata_App_HttpException $httpException) {
$update_error['response_body'] = $httpException->getRawResponseBody();
$update_error['error'] = 1;
} catch (Zend_Gdata_App_Exception $e) {
$update_error['message'] = $e->getMessage();
$update_error['error'] = 1;
}
This code has worked perfectly fine before, but does not work with the older API key, or the newer one generated inside the Google APIs console.
I'm attempting a simple upload and this concerns me greatly:
"The service account flow supports server-to-server interactions that do not access user information. However, the YouTube Data API does not support this flow. Since there is no way to link a Service Account to a YouTube account, attempts to authorize requests with this flow will generate a NoLinkedYouTubeAccount error."
From all reports it seems that Google has forced YouTube uploads to become interactive in all cases precluding all possibility of platforms that automatically upload generated content from working at all.
Any help or insights into the process is appreciated.
P.S - Ohhh, it's been awhile since I looked at that system and Google shut down the YouTube Developer Forums and said "YOU" were responsible for their support now :)
OAuth2 does support the ability to avoid user interaction through the offline access type parameter (ie, using access_type=offline). Check out Google documentation for details.
The solution is really rather simple. Your app needs to use oauth to request offline access. It will be given an access cide which you convert to a refresh token, which is the thing you store in your database. This doesn't expire. Well actually it sometimes does, but that's another story. Whenever you need to access the api, use the stored refresh token to request an access token which you include in each api call.
See https://developers.google.com/accounts/docs/OAuth2WebServer for details.
I don't know what you did but https://code.google.com/apis/youtube/dashboard/gwt/index.html works perfectly fine for me. Maybe it was a temporary issue. If you want no user interaction you HAVE to use YouTube API v2 OR you have to use v3 with methods that don't require authentification OR you have to provide your own youtube account credentials which is not recommended and probably not appropriate for you situation.
Several issues to respond here, I think.
1) The older API console has not been removed, but I've noticed intermittent outages to it and to the newer API console while Google is rolling out their new "cloud console."
2) ClientLogin was officially deprecated in April of 2012, not just 48 hours ago. Jeff Posnick has detailed all the changes over the months (and related ones, such as AuthSub, Youtube Direct, etc.) at his blog (apiblog.youtube.com).
3) You're right that, with v3 of the APIs, you cannot do automatic uploads across the board, as the oAuth2 flow requires user interaction. However, given the limited description of your use case, using refresh tokens is probably your best bet. If the content is user generated, somewhere they must be logging into your app, correct? (so that your app knows which credentials to leverage to do the uploads). At the point they're logging into your app, and you're starting the oAuth2 flow, you just have to hit the first oAuth endpoint and pass it the parameter access_type=offline (along with any other parameters). This will ensure that, when they grant that initial permission, you're returned a refresh token instead of an access token. With that refresh token, you can exchange it for multiple access tokens as needed (an access token lives for about an hour. I don't know how long a refresh token lives, but I've never had one expire before my own login cookies did, and then I just get a new one when my users re-login to my app).
Here's some more info on how to use the refresh token; note, too, that the various google api client libraries make it pretty smooth.
https://developers.google.com/accounts/docs/OAuth2WebServer#refresh
Also, this video tutorial from a Google Developers Live broadcast a couple of months ago might help illustrate the point: http://www.youtube.com/watch?v=hfWe1gPCnzc -- it's using the oAuth playground rather than a client library, but the concept is the same.
The answer is to use google-api-php-client, create an interactive auth page, and set up YouTube API v3 correctly with the new API console.
You can create a very simple page that will authenticate for the supplied channel and then store the correct token in your database. Is already working and uploading hundreds of videos on one channel. You do need to remember to fully activate yourself under the new API console and add the services required. Just keep authenticating and adding the services it says it needs. After that, the regular v3 upload process works just fine. On failure send a group an email and they can get a new token in 10 seconds.
Not the most elegant solution, but the documentation from Google is far from elegant anyways that Stack Overflow is now their front line support.
Just hang in there, a solution is always found. Don't give up!
I didn't get here by myself either, the other answers on this page helped me get all the way to this point. Thanks guys.
P.S - Don't forget the scopes
$client->setScopes("https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload");

having trouble with Facebook iOS SDK v 3.1.1

My app is now using the Facebook SDK version 3.1.1 for iOS.
On iOS6 I'm noticing strange behavior with the FBSession expirationDate. The date is always set to the year 4001 (distant future?). I've read that this can be related to offline_access permission but we're not asking for that (we did at one time, in a very old version of the app. But this is a fresh install on a clean image.)
Per the FB SDK guidelines we always ask for basic read permissions first via FBSession openActiveSessionWithReadPermissions. The session expiration date returned is always 4001-01-01. Later, when we want to post, we call FBSession reauthorizeWithPublishPermissions, asking for publish_action.
This all seems to work fine until the token expires. I only noticed the expirationDate issue because I found that we were passing expired tokens to the graph API, and those calls were failing.
But this shouldn't happen, right? - whenever the app starts cold we're calling FBSession openActiveSessionWithReadPermissions, and whenever the app becomes active we call FBSession handleDidBecomeActive. This should be correct to refresh any expired active token, yes?
What am I likely doing wrong, and what are some things to check? And why is the expirationDate set to 4001?
Edit:
I think my issue is related to what is described here: Expired access token after openActiveSession for Facebook iOS SDK
I'm not using any of the FB SDK support for calling the graph API's. So I'm not taking advantage of the apparently built-in SDK support for refreshing the iOS6-managed token.
Edit 2:
I think this is an exact duplicate of my issue:
iOS 6 Facebook Login not refreshing access token
also referenced here: http://developers.facebook.com/bugs/441739699216684?browse=search_5099512da57214b73000801
The offline_access permission did in fact return an auth token that expired in the year 4001.
In my experience so far, iOS 6's native FB auth always returns a token whose expiration date is recorded (in your app's plist) as the year 4001 as well, but whose actual expiration date is much different, according to the FB token debugger. In short, don't rely on the value stored on the phone. Somehow there's a disconnect.
I too had the same assumptions as you did (calling FBSession openActive... and handleDidBecomeActive) about my token getting refreshed by calling those methods, but that didn't pan out for me either.
In your updates, you linked to a similar question I posed, and I just added my solution. You can check it out here:
http://facebook.stackoverflow.com/questions/13125430/ios-6-facebook-login-not-refreshing-access-token#answer-13298770
Hopefully this helps!

iOS facebook SDK 3 > Get the signed request

I try to get the signed request to login the user via a webservice but I only have access to the accessToken on FBSession.
I saw this link
Facebook Signed Request for iOS (HMAC SHA256)
who shows how to convert the signed_request but doesn't show how to get it.
Need help :)
If I undersand you right you want your app to login and then make a call to a server where you need to check the users credential again.
I used this tutorial for the authentication.
Then when I call the server I send the accessToken property as a parameter to check the users credentials on the server. You can get the token value like this:
FBSession.activeSession.accessToken
On the server side you can then set the access token to the value you got from the app.
I compiled a gist that generates a signed request which you can then use to authenticate a user on your server without having to query the graph API.
You can find it here: https://gist.github.com/3962188
You can find the original question I compiled it for here: Facebook iOS SDK to return a signed request object upon login
Please note that most of the code is simply a compilation of existing open source code, but I haven't seen any fully working implementation like this anywhere.

Resources