Google Signin for iOS - YouTube Channel ID - ios

I have follows the instructions and implement Google Signin for iOS in test application.
After getting the user profile & token, I want to get the user YouTube channel ID.
I have tried to use the user access token with the following URL but I got exception of "Insufficient Permission"
https://www.googleapis.com/youtube/v3/subscriptions?part=snippet&maxResults=50&mine=true&access_token={oauth_token}
How can I do this in Swift?

Google Signin for iOS implementation which allow you yo signin with your google account. In order to have that ability to get YouTube data it require additional scope configuration as follows:
let scope: NSString = "https://www.googleapis.com/auth/youtube.readonly"
let currentScopes: NSArray = GIDSignIn.sharedInstance().scopes
GIDSignIn.sharedInstance().scopes = currentScopes.arrayByAddingObject(scope)
Now, you can run the following YouTube data API with Access Token:
https://www.googleapis.com/youtube/v3/channels?part=id&mine=true&access_token={oauth_token}
The access token, you will get from user.authentication.accessToken

Related

Insufficient Permission error for Google Drive iOS

I am using Google SignIn for authentication in one of my iOS application. With that I am defining all possible scopes for Google drive use but still getting the following error. I am creating different files on Google Drive.
Domain=com.google.GTLRErrorObjectDomain Code=403 "Insufficient Permission"
UserInfo={GTLRStructuredError=GTLRErrorObject 0x170450d10: {message:"Insufficient
Permission" errors:[1] code:403}, NSLocalizedDescription=InsufficientPermission
I am defining scopes with Google SignIn as:
[[GIDSignIn sharedInstance].scopes
arrayByAddingObject:#[kGTLRAuthScopeDriveFile,kGTLRAuthScopeDrive,
kGTLRAuthScopeDriveMetadata]];
Google Drive API is enable on Google Console but still I do not know why I am getting this error. I also tried to turn on "OAuth 2.0" for Google Drive service on console but google is not allowing me and automatically turn it off. Any help will be appreciated.
Google changed it's authentication policy for it's API's. Now native web views for OAuth flow is not allowed by them but users are pushed to use OS browsers. They also introduced Google SignIn button SDK that is used for user login, if user wants to use Google Service. Google SignIn button(GIDSign) handle some authentication flow for users. Users can also use updated "GMTAppAuth" and "AppAuth" for implementation of GTMFetcherAuthorizationProtocol for authorizing request for AppAuth. I was using Google Drive API in one of my application and using "GTMOAuth2ViewControllerTouch" for Google Sign In and authentication but after update, it stopped working. In my above mentioned question, I am using Google SignIn for authentication. In old code, you can use Authentication NSString* constants "GTLRAuthScopeDriveFile" to define scope but now they changed the way and that's why I am getting error.
Old way of defining scope:
- (GTMOAuth2ViewControllerTouch *)createAuthController {
NSArray *scopes = [NSArray arrayWithObjects:kGTLRAuthScopeDriveFile, kGTLRAuthScopeDrive,nil];
authController = [[GTMOAuth2ViewControllerTouch alloc]
initWithScope:[scopes componentsJoinedByString:#" "]
clientID:kClientID
clientSecret:nil
keychainItemName:kGTMAppAuthKeychainItemName
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
return authController;
}
New corrected way:
NSString *driveFile = #"https://www.googleapis.com/auth/drive.file";
[GIDSignIn sharedInstance].scopes = [currentScopes arrayByAddingObject:driveFile];

Google Classroom, Ruby, Rails: #NotGoogleAppsUser with test account

I've got a test account for Classroom from Google (that is, all services apart from Classroom are disabled for it). Following the example as in https://developers.google.com/classroom/quickstart/ruby (with slight modifications), I'm able to log in and fetch details e.g. about the student's courses.
However what I want to do is utilize it in a Rails app. I'm using omniauth-google-oauth2 and google-api-ruby-client (the new 0.9.x branch). After having fetched the token for that test account from Google (I've triple checked that it is this account and not any other profile I use) I'm trying to access data from Google::Apis::ClassroomV1::ClassroomService, but it keeps telling me:
Sending HTTP get https://classroom.googleapis.com/v1/courses?pageSize=10
403
#<Hurley::Response GET https://classroom.googleapis.com/v1/courses?pageSize=10 == 403 (319 bytes) 748ms>
Caught error forbidden: #NotGoogleAppsUser The user is not a Google Apps user.
Error - #<Google::Apis::ClientError: forbidden: #NotGoogleAppsUser The user is not a Google Apps user.>
Google::Apis::ClientError: forbidden: #NotGoogleAppsUser The user is not a Google Apps user.
The code I use is:
require 'google/apis/classroom_v1'
module GoogleIntegration::Client
Classroom = Google::Apis::ClassroomV1
def self.create(token)
service = Classroom::ClassroomService.new
scopes = ['https://www.googleapis.com/auth/classroom.courses.readonly', 'profile', 'email']
service.authorization = Google::Auth.get_application_default(scopes)
service.authorization.access_token = token
service.client_options.application_name = 'Membean Classroom Sample'
service
end
and in the controller:
service = GoogleIntegration::Client.create(request.env['omniauth.auth'].credentials.token)
response = service.list_courses(page_size: 10)
According to Classroom API Access Errors:
NotGoogleAppsUser indicates that the requesting user does not belong
to a Google Apps domain.
Possible Action: Prompt the user to re-authenticate using a "Google
Apps for Education" account. Provide a link to using multiple
accounts so the
user can select the correct account.

Youtube : Multiple accounts authentication (OAuth) to upload video to single account/channel

I am integrating video upload to Youtube from iOS application.
Steps followed :
Created Google account and enable Youtube data API for the account in developer console.
Created client ID and client secret and incorporated in the application.
Checked out Google API objective C client for Youtube upload which is normally a MAC tool, i just modified for iOS.
Run the application.
It will prompt for Login (OAuth).
Case # 1
Use the same account for Login, which used for creating client ID and
Client secret.
Accept the scopes and assign the authorizer to Youtube service.
GTMOAuth2ViewControllerTouch :
completionHandler:^(GTMOAuth2ViewControllerTouch *viewController,
GTMOAuth2Authentication *auth, NSError *error)
{
self.youTubeService.authorizer = auth;
}
start upload and it working fine.
Case #2
Use Different account for login.
Accept the scopes and assign the authorizer to Youtube service.
GTMOAuth2ViewControllerTouch :
completionHandler:^(GTMOAuth2ViewControllerTouch *viewController,
GTMOAuth2Authentication *auth, NSError *error)
{
self.youTubeService.authorizer = auth;
}
start upload and it causing : Error Domain=com.google.GTLJSONRPCErrorDomain Code=-32602 "The operation couldn’t be completed. (Unauthorized)" UserInfo=0x986abe0 {error=Unauthorized, GTLStructuredError=GTLErrorObject 0x98528d0: {message:"Unauthorized" code:-32602 data:1}, NSLocalizedFailureReason=(Unauthorized)}
Note : If i uses same account (used to create client ID and secret) to login and upload, it is working fine and video is displaying in Youtube.
But whenever trying with other account to upload it causing problem even in Google API objective C client application too.
let me know if i missing any other cases to be consider to do so.
thanks.
You may be doing Auth wrong, or the user may not have a valid connect YouTube channel.
You can check YouTube Direct Lite for iOS project for the best example.
After a day of search/testing, finally found the cause.
There is nothing wrong with my OAuth process.
The cause is other multiple accounts (not the one used to create Client ID and Client Secret) was not having a channel in Youtube.
Solution :
If user account is new to Youtube, then youtube won't have a channel for that account.
User need to create one (that's easy, Youtube itself will alert to create new channel when, My Channel from left side pane is get selected)
If user account have valid channel, then the above "Unauthorized" error won't be happen.

Authentication with Twitter using the Twitter access token on Azure (using iOS Twitter reverse Auth)

I'm currently working on an iOS app which will (if I can figure out this problem) use Azure as backend. The user is supposed to login with their iOS account which they already setup on their iOS device. I than use reverse authentication (https://dev.twitter.com/docs/ios/using-reverse-auth) to get the user's access token and I would like to use said access token to login the user.
I tried using (Swift snippet)
let tokenDictionary = ["access_token": "<token-I-got>"];
client.loginWithProvider("twitter", token: tokenDictionary.bridgeToObjectiveC(), completion: {(user: MSUser!, error: NSError?) in
if let user = user? {
print(user.userId)
} else if let error = error? {
print(error)
}
})
but the only thing the API returns is:
POST of Twitter token is not supported.
Any ideas how I could get this to work or do I have to switch away from Azure to something different? (And using the webview for login is not an option, as we have this nice already accounts on iOS already setup with the credentials).
Thanks for helping.
This feature is not currently supported by Azure Mobile Services. You can upvote the feature request here.

Why is the access token that I pass to appEngine from iOS invalid?

I am working on an iPhone game that maintains a leaderboard and some social interaction through a backend that I built in Google App Engine. The user can log in through facebook in the iPhone app. The app sends some user details including the access token to my Google App Engine app through an HTTP post.
The handler that receives the request tries to use the access token to retrieve the users friends. I am using the pythonforfacebook SDK (which I have had success with previously) which is on Github here:
https://github.com/pythonforfacebook/facebook-sdk
The relevant python code in my GAE app is as follows:
def post(self):
at = self.request.get('at')
user = User.get_by_key_name(uid)
if not user: #create previously unknown user
logging.info('Entered unknown user code')
logging.info(at)
logging.info(type(at))
graph = facebook.GraphAPI(at)
facebook_user = graph.get_object("me")
friends = graph.get_connections(facebook_user["id"], "friends")
The logging commands print what looks like a good access token and states that the type is 'Unicode'. When I copy the access token that logging.info prints to the GAE logs and paste it into the facebook access token debugger, I get the following output:
App ID: deleted for privacy but looks right
Metadata: {"sso":"iphone-safari"}
User ID: deleted for privacy but looks right
Issued: 1345405177 (10 minutes ago)
Expires: Never
Valid: True
Origin: Mobile Web Faceweb
Scopes: offline_access read_stream
I just updated my code to use the most recent posted version of pythonforfacebook but that didn't make any difference. Any ideas would be much appreciated.
Thanks,
Dessie
To get friends of the user you can do it pretty easily without the pythonforfacebook SDK.
https://graph.facebook.com/<username or ID>/friends?access_token=<your token>
That link will give you the friends of the user in JSON format. So if you import urllib2 and json you could do:
response = urllib2.urlopen(<url above>)
friendsString = response.read()
friends = json.loads(friendsString )
Then friends will be a dict containing of all the friends.

Resources