Google Photos API - authentication - api

I'm trying to get list of my shared albums from Google Photos.
I found a enable Photos API in Google Developers Console.
HTTP GET:
https://content-photoslibrary.googleapis.com/v1/sharedAlbums?key=AIzaSyCkXXXXXXXXXXXXXZiOSe9IiyM8E
RESULT:
{ "error": { "code": 401, "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "status": "UNAUTHENTICATED" } } 1
Configuration in developers console:
Please, what I'm doing wrong? Thank you.

Google API need an access token to make sure that the user has the permission to access the feature. Access token is just like cookie that should be send together with the request.
Usually you will need so many setup to get the access token with your own code. But there are a client library that can help you access Google API with small setup.
Access token also has a lifetime, so if you don't use the library you will need to manually refresh the token.

You need to configure OAUth 2.0 credentials (client ID and secret) and not an API key. More details are in the developer documentation here: https://developers.google.com/photos/library/guides/get-started#request-id
The Google Photos library API acts on behalf of a user, that's why you need to authenticate via OAuth 2.0. As part of this request you also need to specify a scope for your users to accept, see this page for more details: https://developers.google.com/photos/library/guides/authentication-authorization

I've been working on a python project to backup google photos library and album info. you can probably modify it to do exactly what you want. It is fully working but does not currently distinguish between shared and private albums.
https://github.com/gilesknap/gphotos-sync
In particular, see https://github.com/gilesknap/gphotos-sync/blob/master/gphotos/authorize.py which handles authentication and authorization for any Google service (it also handles storing the token and refreshing the token).

Related

Having problem Authorizing Authenticated user account in Web API

I'm using ASP.Net Core 6 to build a secured Web API.
HOW I BUILT IT
dotnet new webapi --auth SingleOrg --aad-instance https://login.microsoftonline.com/ --client-id <CLIENT ID> --domain company.onmicrosoft.com --tenant-id <TENANT ID> --calls-graph true -o GraphTestService
APP REGISTRATION OF WEB API
I added a Scope in the Export API "EmployeeRecord.Read"
APP REGISTRATION FOR CLIENT (Public Client)
Added permission for Graph API (User.Read)
Added permission "EmployeeRecord.Read"
HOW I GET TOKEN USING THE CLIENT
I'm using "InteractiveBrowserCredential".
Everything works fine up until the Web service tries to call Graph API. It throws MsalUIRequiredException.
Understandable, since I did not include any graph API permissions when I requested a token.
FINALLY, THE PROBLEM
When I inspect the Bearer token that's returned, it has the "EmployeeRecord.Read" scope. Ok, that's fine. The Web API authorizes it; but the token doesn't have any permissions for Graph API.
When I add a graph API permission to the scopes, I get
AADSTS28000: Provided value for the input parameter scope is not valid because it contains more than one resource. Scope api://<APP URI ID>/EmployeeRecord.Read https://graph.microsoft.com/User.Read offline_access openid profile is not valid.
If I only include the graph API permission, the Web API returns an Unauthorized error.
WHAT I'VE TRIED
In addition to playing with the scopes, I tried adding my client application to the Web API app registration under the "Expose an API / Add A client Application". This made no difference. No difference in token or errors.
You are trying to add scopes for 2 different resource ,the scope parameter cannot be used to specify permissions for multiple resources similar issue .
we recommend you to use MSAL libarry , MSAL will store tokens for you and refresh whenever token is expired. Just call acquireTokenSilent to get an access token silently, and if you get an error, call acquireToken (see details on error handling here: https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-handling-exceptions#msal-for-ios-and-macos-errors)
for more info please check similar issue
Thanks

invalidAudienceUri error when list files in OneDrive for Business

My Registered Application uses the REST API to synchronize files with "OneDrive for Business". It worked for a year, but recently, my customer reported an error when syncing with "OneDrive for Business". It responds with an error when my app lists or uploads files to it.
For example, listing files in "OneDrive for Business":
https://mydomain-my.sharepoint.com/_api/v2.0/me/drive/items/root/children?select=id,name,size,deleted,folder,file,parentReference,lastModifiedDateTime
"OneDrive for Business" returns the following error:
{
"error": {
"innerError": {
"code":"invalidAudienceUri"
},
"code": "unauthenticated",
"message": "Invalid audience Uri 'https://api.office.com/discovery/'."
}
}
My application has logged correctly into "OneDrive for Business" by OAuth2 and added the authentication header correctly.
Could someone tell me what the cause of the error, how to avoid the problem?
From the hint of Brad, I have resolved the problem, but may not a beautiful way.
Here is the program steps to resolve the problem: (Sorry I have omitted the links, because I can not put too many links)
Show the OAuth2 consent dialogbox, let the user allow the application to access the OneDrive for Business, obtain the Authentication Token (AuthToken).
Use the AuthToken to get the AccessToken and RefreshToken of discovery API. Here is the help of discovery API.
Use the above AccessToken to access discovery API to get the resource URI of your account. The result is like "htts://yourdomain-my.sharepoint.com/";
Show the OAuth2 consent dialogbox AGAIN, let the user allow the application to access the OneDrive for Business, obtain the Authentication Token (AuthToken2).
Use the AuthToken2 to get the AccessToken2 and RefreshToken2 of "htts://yourdomain-my.sharepoint.com/".
Access your "OneDrive for Business" resource by AccessToken2 and RefreshToken2.
Old OneDrive for Business API need not Step4 and Step5, just use AccessToken and RefreshToken to access the resources, but new APIs need Step4 and Step5.

Facebook graph api get the user's infomation

I want to make a website which users can see their posted pictures on the page.
I have signed up for facebook API and have an app id and app secret.
https://graph.facebook.com/oauth/access_token?client_id={#}&client_secret={#}&grant_type=client_credentials
I send users to the oauth to get the user's access token but I don't know what to do next.
https://graph.facebook.com/v3.0/me?fields=id,name,posts&access_token={#}
I thought this would work but I had the error below
"An active access token must be used to query information about the current user.",
The URL you are using to get the Access Token is actually an App Token API.
To generate the Access Token Please replace
https://graph.facebook.com/oauth/access_token?client_id={#}&client_secret={#}&grant_type=client_credentials
with
https://www.facebook.com/v3.0/dialog/oauth?response_type=token&client_id={#id}&redirect_uri={#}&scope=publish_pages
add a redirection url here where the token is published.
OR
better option is to use the login button mentioned here.
https://developers.facebook.com/docs/facebook-login/web/login-button
Also you can read here about all Access Tokens
https://developers.facebook.com/docs/facebook-login/access-tokens/

How to log external in .net web api 2

I'm trying to log in and register with external authentication using MVC5, web api 2 and templates from it.
I don't know how to do it. I read
asp.net web api 2: how to login with external authentication services?.
When I call
GET /api/Account/ExternalLogins?returnUrl=%2F&generateState=true
response is
{
"Name": "Facebook",
"Url": "/api/Account/ExternalLogin?provider=Facebook&
response_type=token&
client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A6685%2F&
state=Yj1...hU1",
"State": "Yj1...hU1"
}
(I don't know what is State for)
Then i can use the Url above (authentication is with cookies) and response is OK html status and some html page (i dont know why)
This call
GET /api/Account/UserInfo
response info with null loginProvider.
I want to register user with FB or Google, so i need token, but i don't know whitch access_token and how can i get it. In example (link above) is this:
POST /api/Account/RegisterExternal
Authorization: Bearer VPcd1RQ4X... (access_token from url)
Content-Type: application/json
{"UserName":"myusername"}
but what is
access_token from url ?
So, my questions are:
How can I external register / login with web api 2 templates?
What is State for? (seems like useless)
External login is Web Api is supported out of the box and can be easily plugged in using the Owin pipeline. Gettting the access token and performing all the oauth related calls are done by the Facebook Owin Provider.
You can find a sample of facebook login with a web site here

Error code 403 in Google+ api

I got "error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
When i try to fetch User Profile in Google+ api by https://www.googleapis.com/plus/v1/people/me URL String.If anyone have any suggestion then please tell me as soon as possible.Thanks in advance for your time.
That message implies that you haven't set up a Google APIs console project.
Create a Google APIs Console project
On the Services pane, enable all of the APIs that your project requires.
On the API Access pane, click Create an OAuth 2.0 client ID. A dialog opens. Fill in your project's information. Click Next
Choose the appropriate application type. Based on the tags you used for this post, I am guessing this is an iOS project so select Installed application.
Enter your bundle ID. You don't need to enter an App Store ID until your app is listed there.
Click Create Client ID.
You will see the client ID and client secret values. You will use these values to enable communication with your project and the Google APIs.
If you aren't already using it, see the Google+ iOS SDK and documentation for a full walk through. The task called "write moments" is similar in implementation and demonstrates how to connect to and use the Google+ REST APIs from within an iOS project that uses the SDK.
You'll need to specify the scope of plus.me to get the profile information.
I got the same error and after much hunting I found that, in my case, the Authorization header with the access token was not set. Set Authorization: "Bearer <YOUR_ACCESS_TOKEN>" in the header of the request of EVERY Google API call.
I just want to add a little information here in the rare case that someone runs into this problem.
I have an organization (ORG). I created a second channel (SC) with some playlists, that referenced videos from ORG.
I made the mistake of assuming that because ORG owned SC, that I could use the same oauth credentials from ORG to access both. I was wrong.
I switched credentials and was confused when I could access the playlists but not the videos. Again, I needed credentials for each one separately to access the resources on the respective channel.
Lame, but that was how it was.
BrettJ's answer will cover most of the bases. However, you will also get this error - even when your credentials are properly authenticated - when the scope is not properly set up. I would check the scope setting in your OAuth dance. Make sure your user is permitted to do the thing your code is trying to help them do.
On top of what BrettJ has mentioned, it is important to send the authorization header for the request done to fetch UserProfile in google+ API.
For example, Add the following header
key: Authorization
value: Bearer ya29.Ci-cA_CywoVdVG#######
For what it's worth, I also got this error when using rclone to sync files and my firewall wasn't configured to allow that traffic.