iPhone Google+ Login and OAuth2 in Backend - ios

Looking the tutorial of using Google+ SDK for iOS in this link, I am able to configure the project and grant my application to obtain an access token. However, I do not want to consume the token in the device to obtain its name, email, etc. I want to obtain a temporal access code (that can be changed for an OAuth2 token) or a id token as I do in my Android application. This is called by google the cross-client identity.
The idea is that the backend server will received this exchange code and will generate the access token to fetch the user profile, email, etc. Then the user is registered with this information. However the access token being generated by the iOS app can be only consumed by the application itself, since the application id used is the id of the iOS application. I have tried to change application id with the server application id, but then it is thrown a redirect_uri_mismatch.
Trying to consume the access token directly in the server will provoke a Google_OAuth_Exception, as the server client id is not equal to the application client id.
I have another approach running based on opening a web page, but I wanted to use the native Google+ login process.
Any idea?

We are working on this feature. This will allow the application to get a "code" that you can send to your server to store offline access.
Sorry you'll have to wait a couple of weeks (sorry don't have an exact date).

Naveen's answer is correct, but if you just need basic profile information and email address you can use the id token instead. This will include the email address (as long as you requested the email scope), and the user ID which can be used to query for public profile information from the Google+ API, without needing to pass a code or access token. Retrieving the ID token is really easy
[GPPSignIn sharedInstance] setHomeServerClientID:#"911581857976.apps.googleusercontent.com"];
- (void) finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error {
if (error) {
NSLog(#"Error: %#", error);
return;
}
NSLog(#"ID Token: %#", [[GPPSignIn sharedInstance] idToken]);
}
I wrote up a longer example in a blog post a while back, which might help: http://www.riskcompletefailure.com/2013/11/client-server-authentication-with-id.html

Quick answer might be to configure additional redirect URLs in the Cloud Console.

As of today this is available: https://developers.google.com/+/mobile/ios/sign-in#enable_server-side_api_access_for_your_app

Related

'Error in call to API function \"files/list_folder\": This app is currently disabled' on iOS

I have that message error, but I don't understand why it comes. I reinstalled a new version, and I use that code to check if it is well authorized to DropBox:
if (([DBClientsManager authorizedClient] && [DBClientsManager authorizedTeamClient]))
It says me ok, but when I send the content to my dropbox account, I have that response:
ErrorContent = "Error in call to API function \"files/list_folder\": This app is currently disabled.";
RequestId = 51e8ef6340500ad7aacee5ffb32c3489;
StatusCode = 400;
UserMessage = nil;
I authorized it three days ago for information.
But if I connect to dropbox again, with that code:
[DBClientsManager authorizeFromController:[UIApplication sharedApplication]
controller:self
openURL:^(NSURL *url) {
[[UIApplication sharedApplication] openURL:url];
}];
it is ok, it works.
My question is, how can I really know if the user can send or not content to his dropbox account without asking the authorization everytime and how long expired the token?
May be the token is not valid anymore? May be he is not authorized because the time is expired?
Thanks in advance.
The authorizedClient and authorizedTeamClient properties only check if you have an access token stored locally. They don't indicate if that access token is still valid.
Dropbox API access tokens don't expire by themselves, but they can become invalid for a variety of reasons. For example, users and apps can explicitly revoke tokens. You can't be sure if an access token is still valid unless you attempt an API call with it. For example, you can try it by calling getCurrentAccount
In your case, this access token was no longer valid because the app that it is for is disabled. (That is, the developer either disabled the Dropbox API app from the Dropbox App Console, or the account that owns the app itself was disabled.)

iOS Google Signin Doesn't Work Properly With New Scopes

In a deprecation announcement from Google, they say that developers need to migrate away from these scopes:
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile
and instead use these scopes:
email
profile
After doing so on my App-Engine backend, however, I'm having problems with my iOS app. On first run, it asks me to sign in and the screen shows both scopes correctly after which the app runs just fine. On the second run, where it is supposed to retrieve the authorization credentials from protected storage, it does not work as the App-Engine server is receiving null for the User parameter in the endpoint.
The App-Engine endpoint requires both the email and profile scope. The iOS code for retrieving previous credentials is:
GTMOAuth2Authentication* auth =
[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:AUTH_KEYCHAIN_NAME
clientID:Constants.IOS_CLIENT_ID
clientSecret:Constants.IOS_CLIENT_SECRET];
and the iOS code for authenticating should there be no previous credentials is:
viewController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:Constants.EMAIL_SCOPE
clientID:Constants.IOS_CLIENT_ID
clientSecret:Constants.IOS_CLIENT_SECRET
keychainItemName:AUTH_KEYCHAIN_NAME
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
This used to work just fine! Now the App-Engine server changed the email scope from .../userinfo.email to email and the profile scope from .../userinfo.profile to profile. The iPad app exhibits the same behavior against the new backend with Constants.EMAIL_SCOPE set to either value.
The google-api-objectivec-client library is v0510, the latest.
The Android version of my app continues to work just fine without any code changes after the backend change.
Update 2015-02-26: Now using r424 (2014-12-30) of google-api-objectivec-client. No change. If the AppEngine backend is using the new "profile" and "email" scopes, the iOS app cannot authenticate on the second (or later) run where it is loading the credentials from store rather than going through the sign-in flow.
The AppEngine log of the first (sign-in credentials) shows:
com.google.api.server.spi.auth.GoogleIdTokenUtils getCurrentUser: getCurrentUser: IdToken; email=testuser#gmail.com
The AppEngine log of the second (loaded credentials) shows:
com.google.api.server.spi.auth.AppEngineAuthUtils getCurrentUser: getCurrentUser: AccessToken; Tried and failed to get client id for scope 'com.google.api.server.spi.config.scope.DisjunctAuthScopeExpression#a015b54e'
com.google.appengine.api.oauth.InvalidOAuthParametersException:
at com.google.appengine.api.oauth.OAuthServiceImpl.makeSyncCall(OAuthServiceImpl.java:139)
at com.google.appengine.api.oauth.OAuthServiceImpl.getGetOAuthUserResponse(OAuthServiceImpl.java:118)
at com.google.appengine.api.oauth.OAuthServiceImpl.getAuthorizedScopes(OAuthServiceImpl.java:90)
at com.google.api.server.spi.auth.AppEngineAuthUtils.getOAuth2AuthorizedScopes(AppEngineAuthUtils.java:140)
at com.google.api.server.spi.auth.AppEngineAuthUtils.getCurrentUser(AppEngineAuthUtils.java:89)
...
This exception does not propagate up; null is returned for the user.
Is there something else that needs to be done for the GTMOAuth2ViewControllerTouch to work correctly with the new scopes? Or is there perhaps something wrong on the AppEngine side?

.NET - Update status (tweet) to Twitter without PIN or real Callback url?

I'm trying to write an app that can tweet using an 'application' I registered with Twitter. I am using TweetSharp and have tried to get my TwitterService set up as follows:
public Twitter(string consumerKey, string consumerSecret)
{
this.twitterService = new TwitterService(consumerKey, consumerSecret);
OAuthRequestToken oAuthRequestToken = this.twitterService.GetRequestToken();
Uri uri = this.twitterService.GetAuthorizationUri(oAuthRequestToken);
Process.Start(uri.ToString());
OAuthAccessToken oAuthAccessToken =
this.twitterService.GetAccessToken(oAuthRequestToken);
this.twitterService
.AuthenticateWith(oAuthAccessToken.Token, oAuthAccessToken.TokenSecret);
}
It gets to the OAuthAccessToken line and then takes me to the Authorize [my app] to use your account? page on the Twitter website. Before I specified a phony callback url, it displayed a page with the PIN that my user is supposed to enter when I clicked the 'Authorize app' button. Then when I added a phony callback url, it would attempt to go to that page and my code would blow to smithereens with the following error:
The remote server returned an error: (401) Unauthorized.
What I want to know is: can I tweet programatically without the need to enter a PIN or have a legitimate callback url?
Tweets must be sent in the context of a user. (Ref: POST statuses/update.) Therefore, your app must get the user's authorization (an OAuth access token) in order to send a Tweet. Since you can't get an access token without using either PIN-based authentication or a callback URL, I'm afraid that what you are asking simply cannot be done.
If, however, you just want to avoid prompting your users to enter the PIN each time they start your app, then the answer is simple: Once you have a valid access token, save it somewhere (e.g. to a file) and then reload it next time your app runs. For my WinForms app, I use .NET's built-in per-user Settings mechanism to store the Access Token and Access Token Secret. A web app would probably be better off using a database or similar to persist access tokens.
Note: If you do this, you'll also need to check the validity of the stored access token, and repeat the authorization process if it's no longer valid. The Twitter API documentation suggests using the GET account/verify_credentials method for this purpose.

FB iOS SDK 3.2: Why do I need an access token for logging a conversion pixel?

I'm trying to log a conversion pixel with Facebook SDK iOS 3.2 by calling
[FBInsights logConversionPixel:<pixelID> valueOfPixel:0]
Now...
I'm doing this before I know the user logged in with facebook, so it's not certain I have an active FBSession with a user access token to this app.
In result I get the following error:
{
code = 100;
message = "(#100) Graph API for app id <appID> called, but token has app id 0";
type = OAuthException;
}
If the user logs in to facebook and then log the conversion, everything works fine.
The thing I don't get is why do a logging of a conversion pixel needs to happen from an authorized session, in the php code of the app I can simply go to https://www.facebook.com/offsite_event.php?id=<pixelID>&value=0 without any access token and it will mark my conversion pixel.
Any thoughts/ideas of how can use FBInsights without an active session?
If this problem still actual (maybe will actual for someone), then you can try set Client token for FBSettings class
[FBSettings setClientToken:#"<your app client token>"];
You can get client token on your app settings page - Advanced - Security section. There should be checkpoint "Client token" that set to OFF. Just set it ON and save changes, then you get client token

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