Apple's JS Sign in implementation (https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms) seems to be returning User's Information in the following format:
{ "name": { "firstName": string, "lastName": string }, "email": string }
though the same flow through the REST API does not return the User's Info
https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens
Is there anything that needs to be set explicitly in order to get the user info(first name and last name) from a rest API call?
Related
I am trying to retrieve all the organizations in my account but in the documentation an organization is always required in the API call.
https://dev.azure.com/{organization}/_apis/...
If you load the current landing page, it displays all your organizations tied to your account. I assumed it had to get that information some way. I captured the network traffic and I believe you could get to the data you want using a system API call. However, it might change or might become unsupported without notice, so use at your own discretion.
You can get the information you want using this API:
Post https://dev.azure.com/{organization1}/_apis/Contribution/HierarchyQuery?api-version=5.0-preview.1
Body:
{
"contributionIds": ["ms.vss-features.my-organizations-data-provider"],
"dataProviderContext":
{
"properties":{}
}
}
Response:
{
"dataProviderSharedData": {},
"dataProviders": {
"ms.vss-web.component-data": {},
"ms.vss-web.shared-data": null,
"ms.vss-features.my-organizations-data-provider": {
"organizations": [
{
"id": "{redacted id}",
"name": "{organization1}",
"url": "https://{organization1}.visualstudio.com/"
},
{
"id": "{redacted id}",
"name": "{organization2}",
"url": "https://dev.azure.com/{organization2}/"
}
],
"createNewOrgUrl": "https://app.vsaex.visualstudio.com/go/signup?account=true"
}
} }
you can do it simply by making a call to get all the account you are member/ owner of. However for that you need your id, which can be easily fetched by making get profile call. Here are steps below:
Make a VSTS API call to get profile details using Bearer token or PAT
https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=5.1
This will return you, your Id:
{
"displayName": "xxxx",
"publicAlias": "xxx",
"emailAddress": "xxx",
"coreRevision": xxx,
"timeStamp": "2019-06-17T09:29:11.1917804+00:00",
"id": "{{We need this}}",
"revision": 298459751
}
Next, make a call to get all the accounts you are member of or owner of:
https://app.vssps.visualstudio.com/_apis/accounts?api-version=5.1&memberId={{Your Id}}
Response:
{
"count": 1,
"value": [
{
"accountId": "xxx",
"accountUri": "xxx",
"accountName": "xxx",
"properties": {}
}
]
}
It will return list of accounts you are associated with.
A REST API request/response pair can be separated into five components:
The request URI, in the following form:
VERB https://{instance}[/{team-project}]/_apis[/{area}]/{resource}?api-version={version}
instance:
The Azure DevOps Services organization or TFS server you're sending the request to.
They are structured as follows:
Azure DevOps Services: dev.azure.com/{organization}
The REST API's are organization specific. This is not documented at present. You could submit a feature request here: https://developercommunity.visualstudio.com/spaces/21/index.html
Our PM and product team will kindly review your suggestion. Sorry for any inconvenience.
As a workaround, you could use the API which captured from network traffic just as Matt mentioned.
We've been using "https://app.vssps.visualstudio.com/_apis/accounts" without specifying any API version and this returns all our accountnames
This is still working for us, but because of some other issues we have I'm adding the api version to all our api calls, however. For this I also run into the fact that https://learn.microsoft.com/en-us/rest/api/azure/devops/account/accounts/list?view=azure-devops-rest-5.0 requires an member or owner id.
Retrieving that needs an account/organization so it is a bit of a catch 22 situation.
For now I'll stay with just "https://app.vssps.visualstudio.com/_apis/accounts" I guess
I'm getting a sign-in response for both "app.vssps.visualstudio.com/_apis/accounts" and
Post https://dev.azure.com/{organization1}/_apis/Contribution/HierarchyQuery?api-version=5.0-preview.1
StatusCode : 203
StatusDescription : Non-Authoritative Information
EDIT:
Nevermind, it worked using the static MSA clientid and replyURL:
internal const string clientId = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1"; //change to your app registration's Application ID, unless you are an MSA backed account
internal const string replyUri = "urn:ietf:wg:oauth:2.0:oob"; //change to your app registration's reply URI, unless you are an MSA backed account
//PromptBehavior.RefreshSession will enforce an authn prompt every time. NOTE: Auto will take your windows login state if possible
result = ctx.AcquireTokenAsync(azureDevOpsResourceId, clientId, new Uri(replyUri), promptBehavior).Result;
Console.WriteLine("Token expires on: " + result.ExpiresOn);
var bearerAuthHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Headers
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("User-Agent", "ManagedClientConsoleAppSample");
client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
client.DefaultRequestHeaders.Authorization = authHeader;
//Get Organizations
client.BaseAddress = new Uri("https://app.vssps.visualstudio.com/");
HttpResponseMessage response1 = client.GetAsync("_apis/accounts").Result;
As the Graph API documentation says, the /comment retreives a Comment Object, which contains a from attribute, which represents the user that made the comment. By default, that from attribute comes with an id and a name.
Although I know I can get the profile image with the id, it will depend on the access_token as the way would be like this:
return 'https://graph.facebook.com/' + id + '/picture?type=large&access_token=' + accessToken;
How can I do to get the profile img of the commentator without depending on the access_token? Because when the API retreives a User object, in the fields object, you can request { fields: "id,name,picture }. But how can i do to ask for the picture to the from attribute that comes in the Comment object? As this is not allowed { fields: "id,name,from.picture }
You should be able to ask for second level attributes
https://developers.facebook.com/docs/graph-api/using-graph-api/#fieldexpansion
$ fbapi '/v2.6/me/photos?fields=from{picture}' | jq '.data[0]'
{
"from": {
"picture": "https://scontent.xx.fbcdn.net/v/t1.0-1/xxxx/p50x50/xxxx.jpg",
"id": "9999999999"
},
"id": "000000000"
}
What is a correct rest way of getting a resource ID by a field, for example a name. Take a look at the following operations:
GET /users/mike-thomas
GET /users/rick-astley
I don't want to use these operations at my API end, instead I want to write an API operation that will get me the ID when submitting a field (name in the case of users) for example:
GET /users/id-by-field
Submitted data:
{
"fullName": "Mike Thomas"
}
Return data:
{
"data": {
"id": "123456789012345678901234"
}
}
What you want is known as an algorithmic URL where the parameters for the algorithm are passed as URL parameters:
GET /users?name="Mike Thomas"
Advantages are that you are using the "root" resource (users) and the search parameters are easily extended without having to change anything in the routing. For example:
GET /users?text="Mike"&year=1962&gender=M
where text would be searched for in more than just the name.
The resultant data would be a list of users and could return more than the identification of those users. Unless fullName uniquely identifies users, that is what you need to allow for anyway. And of course the list could contain a single user if the parameters uniquely identified that user.
{
users: [
{
id: "123456789012345678901234",
fullName: "Mike Thomas",
dateJoined: 19620228
}
, {
id: "234567890123456789012345"
fullName: "Rick Astley",
dateJoined: 19620227
}
]
}
I have a website and use the login using facebook.
I want to do the following:
User comes to my web site - login with facebook - I read his facebook data and photography permits
For example:
{
"id": "1"
"name": "John English"
"first_name": "John",
"last_name": "English"
"link": "https://www.facebook.com/johnenglish"
"username": "johnenglish"
"gender": "male"
"locale": "en_US"
....
}
and
{
"id": "2"
"name": "John English2"
"first_name": "John",
"last_name": "English2"
"link": "https://www.facebook.com/johnenglish2"
"username": "johnenglish2"
"gender": "male"
"locale": "en_US"
....
}
Both users have a private photo. Can I load the private photos from user (id: 2) with my web application using javascript? Can you give me the example?
I've tried this:
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
FB.api('/USER-ID(USER ID 2)/photos?access_token=' + accessToken, function(response) {
//A user access token is required to request this resource.
});
} else if (response.status === 'not_authorized') {
} else {
}
});
Error: A user access token is required to request this resource.
Have you requested the right permissions when you gained your access token? I don't know how to do it in JS, but you have to tell facebook, that you want you get access to the photos. As I do not work with JS, I request my access token via an URL (see Point 1 here: https://developers.facebook.com/docs/authentication/devices/). In the parameter "scope" you can add the permissions you want to have ( https://developers.facebook.com/docs/authentication/permissions/). Here, you add "&scope=user_photos" (without quotation marks) to the URL.
OK, now I understand your question.
I assume that you already found out the ID of the User 2. I am sorry but I can still not show you how to do it in JS. Though, it may help.
At first, I forgot one permission, you need friends_photos in scope, too.
You now call: http://graph.facebook.com/FRIEND_ID/albums/?access_token=ACCESS_TOKEN.
Type it into your browser, so that you know what I mean: You parse that output and find ids of the albums of your friend.
You get to that album via: http://graph.facebook.com/ALBUM_ID?access_token=ACCESS_TOKEN.
You will find an entry named cover_photo in your output.
Call: http://graph.facebook.com/COVER_PHOTO_ID?access_token=ACCESS_TOKEN and you get access to that photo.
You may now download it via http://graph.facebook.com/COVER_PHOTO_ID/picture?access_token=ACCESS_TOKEN.
Use the URL given in paging -> next to move on to the following photos. It is much easier to follow these steps with a picture in mind, consider that here.
I've noticed some difference in Facebook profiles :
Some of them have the following string format at browser nav bar :
http://facebook.com/john.smith
and the others look like this :
http://www.facebook.com/profile.php?id=100455*
Can someone explain why there is a difference ?
And more important is how can I convert those john.smith like names to id numbers ?
These are alias urls that Facebook offers its users (and pages) - its basically a vanity thing, both the id and the alias url will work the same way.
You can translate the alias (or username) by doing a lookup for that user using the Facebook Graph API. Simply make a GET request to https://graph.facebook.com/John for example - this will serve the following response:
{
"id": "779695190",
"name": "John Chan",
"first_name": "John",
"last_name": "Chan",
"link": "http://www.facebook.com/John",
"username": "John",
"gender": "male",
"locale": "en_US",
"updated_time": "2011-12-27T05:01:06+0000",
"type": "user"
}
response.id is what your interested in.
Test it out: http://developers.facebook.com/tools/explorer?method=GET&path=john
You're not really want to converting the ids to names but getting id by username which is possible by issuing request to Graph API:
GET https:/graph.facebook.com/john.smith?fields=id
Here is a JQuery based solution, where callback is an arbitrary function:
$.get("https://graph.facebook.com/" + name + "?fields=id", function(response){
if(response.error){
callback(false)
}else{
callback(response.id);
}
});