The /geocode endpoint is returning a 401 even when valid credentials are supplied.
The following request:
GET /6.2/geocode.json?app_code=MY_APP_CODE& app_id=MY_APP_ID& searchtext=test HTTP/1.1
Host: geocoder.api.here.com
cache-control: no-cache
returns:
<ns2:Error xmlns:ns2="http://www.navteq.com/lbsp/Errors/1" type="PermissionError" subtype="InvalidCredentials">
<Details>invalid credentials for MY_APP_ID</Details>
</ns2:Error>
I'm on a Freemium plan and I get the above response when I use my app_id & app_code.
EDIT: It seems the demo credentials are domain specific, adding a Referer header with https://developer.here.com as value the request succeeds. But after swapping in app_id & app_code with my own credentials (not touching any other parameter) I suddenly get a 401 (essentially ruling out the possibility that some of the other parameters are borking the request).
Demo App ID and Code are set as domain specific and has expiration date set. So it need not necessarily work in your browser. You should use your own credentials. Using my own credentials for the below example query I am able to get the response.
https://geocoder.api.here.com/6.2/geocode.json?searchtext=200%20S%20Mathilda%20Sunnyvale%20CA&app_id=xxxx&app_code=xxxx&gen=9
Response:
Response
MetaInfo
Timestamp "2019-02-05T13:10:09.436+0000"
View
0
_type "SearchResultsViewType"
ViewId 0
Result
0
Relevance 1
MatchLevel "houseNumber"
MatchQuality
State 1
City 1
Street
0 0.9
HouseNumber 1
MatchType "pointAddress"
Location
LocationId "NT_nL.dzNwdSJgdcF4U8dYEiC_yADM"
LocationType "address"
DisplayPosition
Latitude 37.37634
Longitude -122.03405
NavigationPosition
0 {…}
MapView
TopLeft {…}
BottomRight {…}
Address
Label "200 S Mathilda Ave, Sunn…CA 94086, United States"
Country "USA"
State "CA"
County "Santa Clara"
City "Sunnyvale"
District "Heritage District"
Street "S Mathilda Ave"
HouseNumber "200"
PostalCode "94086"
AdditionalData […]
Related
Ive been trying to do this for a couple of days now and ive double checked everything against examples and tried searching my error response but im not able to come up with anything.
Ive succesfully added graph api calls to my appplication already, when I do a GET on the /users endpoint it returns my AD users just fine, the code below is what I am doing to try and create the user but every time i get ResourceNotFound response.
It may we worth noting that at first I was getting an error message where it wasnt stating the resource it couldnt find, but now the error message is showing 'Resource 'User_' does not exist...'
The GUID changes every time suggesting that it is creating that object and then trying to do something with it but then failing on the API somewhere.
Create User Function -
Public Function CreateUser(user As User) As String
Dim app As IConfidentialClientApplication = MsalAppBuilder.BuildConfidentialClientApplication(ClaimsPrincipal.Current)
Dim accountId = ClaimsPrincipal.Current.GetMsalAccountId()
Dim account = app.GetAccountAsync(accountId).Result
Dim result As AuthenticationResult
Dim scopes As String() = {"https://graph.microsoft.com/.default"}
Try
result = app.AcquireTokenSilent(scopes, account).ExecuteAsync().Result
Catch msalEx As MsalUiRequiredException
Return msalEx.Message
Catch ex As Exception
result = app.AcquireTokenForClient(scopes).ExecuteAsync().Result
End Try
Dim client = New HttpClient()
Dim request As New HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/users")
request.Headers.Authorization = New AuthenticationHeaderValue("Bearer", result.AccessToken)
Dim json = JsonConvert.SerializeObject(user)
request.Content = New StringContent(json, Encoding.UTF8, "application/json")
Dim response = client.SendAsync(request).Result
If response.Content IsNot Nothing Then
Dim responseString = response.Content.ReadAsStringAsync().Result
Return responseString
End If
Return ""
End Function
Something else I noticed is that the app never contains any users so the scope only token is always called.
After posting here I also requested help from the microsoft support team.
They suggested that i use the graph explorer to try again, so after doing both that and re-sending my request in Insomnia I did in fact get a successful response when using the graph explorer and still BadRequest from Insomnia and code.
The difference between these requests was the Request Body.
What I initially built was using the code sample provided in the graph documentation here (Example 1) - https://learn.microsoft.com/en-us/graph/api/user-post-users?view=graph-rest-1.0&tabs=http
To save you some time this is what it looks like -
POST https://graph.microsoft.com/v1.0/users
Content-type: application/json
{
"accountEnabled": true,
"displayName": "Adele Vance",
"mailNickname": "AdeleV",
"userPrincipalName": "AdeleV#contoso.onmicrosoft.com",
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "xWwvJ]6NMw+bWH-d"
}
}
And this is what the request body looks like in graph explorer -
{
"accountEnabled": true,
"city": "Seattle",
"country": "United States",
"department": "Sales & Marketing",
"displayName": "Melissa Darrow",
"givenName": "Melissa",
"jobTitle": "Marketing Director",
"mailNickname": "MelissaD",
"passwordPolicies": "DisablePasswordExpiration",
"passwordProfile": {
"password": "b85dba0d-be1b-a59a-8332-6821b138674d",
"forceChangePasswordNextSignIn": false
},
"officeLocation": "131/1105",
"postalCode": "98052",
"preferredLanguage": "en-US",
"state": "WA",
"streetAddress": "9256 Towne Center Dr., Suite 400",
"surname": "Darrow",
"mobilePhone": "+1 206 555 0110",
"usageLocation": "US",
"userPrincipalName": "MelissaD#{domain}"
}
After changing my code model to match the second request body I now get a successful response in code, and to test the theory I left my old request body in Insomnia and resent the request with a fresh token and it return BadRequest whilst the code returned Success.
I'm not 100% sure what the missing properties are, perhaps just password policies. If Microsoft give me more insight I will update here.
Hopefully this provides someone else with some insight as I really struggled to find information on this one myself.
Try out a few things -
As Tim suggested using the same token and JSON Content and see if you can leverage Postman and call the same API to validate your JSON(request body), URL, and token.
Use jwt.ms and check if your token has all necessary claims.
Make sure you have given required permission to your App.
If you still face same problem, do revert with client-request-id and timestamp so that I can check it better.
Thanks.
Can someone please clarify what status codes should I expect from following situations? For instance, I am sending POST request with such body format:
{
"id": 321,
"username": "tombrown",
"email": "tombrown#gmail.com",
"password": "qwerty123",
"activated": true
}
So the questions are:
1) Should the server return 400 if I specify data of wrong type, for instance, "id": “threetwoone” instead of int, "activated": “yes” instead of boolean etc. Or server should rather return 422 here?
2) The “id” value should be int, but actually it is long int, e.g. 9223372036854774700.
3) Some fields are missing in the body, e.g. I try to send:
{
"id": 321,
"username": "tombrown",
"activated": true
}
Should these examples cause 400, 422 or some other options? What reaction should be correct?
If the JSON is syntactically invalid, return 400. If JSON is syntactically valid but its content is invalid, return 422 to indicate that the request entity cannot be processed by the server.
See the following quote from the RFC 4918 (for your situation, just read JSON when it says XML):
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415 (Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
in below three test cases Get Requests1, Get Requests2 and Get Requests3. I tried to get /RestResponse/result node value by three different way but it show same error
*** Settings ***
Library Collections
Library OperatingSystem
Library HttpLibrary.HTTP
Library RequestsLibrary
*** Test Cases ***
Get Requests1
# create a HTTP session to a server
Create Session countryname http://services.groupkt.com
# store response
${resp}= Get Request countryname /country/get/all
log ${resp.content}
# ${resp.content} display entire json response, now tring to get node value of /RestResponse/result
${getResponseJson} Get Json Value ${resp} /RestResponse/result
# shows error TypeError: expected string or buffer
log ${getResponseJson.content}
Get Requests2
# create a HTTP session to a server
Create Session countryname http://services.groupkt.com
# store response
${resp}= Get Request countryname /country/get/all
log ${resp.content}
# ${resp.content} display entire json response, now tring to get node value of /RestResponse/result
${responseContent}= to json ${resp.content}
# shows error TypeError: expected string or buffer
${getResponseJson} Get Json Value ${responseContent} /RestResponse/result
log ${getResponseJson.content}
Get Requests3
# create a HTTP session to a server
Create Session countryname http://services.groupkt.com
# store response
${resp}= Get Request countryname /country/get/all
log ${resp.content}
# ${resp.content} display entire json response,parse json
${data} Parse Json ${resp}
# shows error TypeError: expected string or buffer
${getResponseJson} Get Json Value ${resp} /RestResponse/result
Json file response
{
"RestResponse": {
"messages": [
"Total [249] records found."
],
"result": [
{
"name": "Afghanistan",
"alpha2_code": "AF",
"alpha3_code": "AFG"
},
{
"name": "\ufffd\ufffdland Islands",
"alpha2_code": "AX",
"alpha3_code": "ALA"
},
{
"name": "Albania",
"alpha2_code": "AL",
"alpha3_code": "ALB"
},
{
"name": "Algeria",
"alpha2_code": "DZ",
"alpha3_code": "DZA"
}
]
}
}
You need to call Get Json Value from the JSON, not from the request object. In your code, ${resp} is an object that includes the JSON data plus other things that json parsers don't know about.
${getResponseJson} Get Json Value ${resp.content} /RestResponse/result
${resp} is a python object. It has the json data, but it also has the HTTP return code and other information. You can't pass it to anything that accepts JSON.
${resp.content} is the body of the HTTP response. Like you write in your comments, this is the JSON data. Any keyword that accepts JSON data should accept this.
${resp.json} is the JSON string of the response converted to a python object. It is no longer JSON, it's a python dictionary. You cannot pass this to any function that requires JSON. You can, however, treat it like a normal python dictionary.
After running the code, ${getResponseJson} will have the data you expect. It is a unicode string, and unicode strings don't have a content attribute.
//body its like this
{
"to":
"/topics/NEWS"
,
"data":{
"extra_information": "This is some extra information"
},
//notification that i need to give
"notification":{
"title": "ChitChat Group",
"text": "You may have new messages",
"click_action":"ChatActivity"
}
}
The 401 error pertains that your Authorization Key is invalid or incorrect.
When using Postman, add a key= prefix for the value of Authorization, like so:
key=AAA...
See below for a tutorial on Sending Downstream FCM Messages using Postman.
Also, for your notification message payload, text isn't one of the valid parameters, I think you were looking for message instead.
Sending Downstream Messages using Postman
To do this in Postman, you simply have to set the following:
Set request type to POST
In the Headers, set the following:
Content-Type = application/json
Authorization = < Your FCM Server Key > (See your Firebase Console's Cloud Messaging Tab)
Set the payload parameters in the Body (*in this example, we used the raw option, see screenshot (2)*)
Send the request to https://fcm.googleapis.com/fcm/send
Screenshots:
(1)
Note: Always keep your Server Key a secret. Only a portion of my key is visible here so it should be fine.
(2)
(3)
Notice that the request was a success with the message_id in the response.
Wrong:
Authorization:AIzaSyDDk77PRpvfhh......
Correct:
Authorization:key=AIzaSyDDk77PRpvfhh......
Full example:
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
While the answers above are still correct, you may choose to use HTTP v1. This requires Bearer instead of key= and uses an Oauth2 access token instead of a server key string. To view HTTP v1 specifications, please refer to the link below:
https://firebase.google.com/docs/cloud-messaging/migrate-v1
I was also getting same error in PHP , solved with below header :
$header = array("authorization: key=" . $this->apiKey . "","content-type: application/json");
I am attempting to retrieve an access token using my refresh token, client id and client secret for the youtube api using R Code.
This is google's example of how to POST a request.
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com Content-Type: application/x-www-form-urlencoded client_id=21302922996.apps.googleusercontent.com&client_secret=XTHhXh1SlUNgvyWGwDk1EjXB&refresh_token=1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ&grant_type=refresh_token
This was my r code:
library(httr)
url<- paste("https://accounts.google.com/o/oauth2/token?client_id=", client_id, "&client_secret=", client_secret, "&refresh_token=", refresh_token, "&grant_type=access_token", sep="")
POST(url)
And I keep getting this response:
Response [https://accounts.google.com/o/oauth2/token?client_id=xxxxxxxxxx&client_secret=xxxxxxxx&refresh_token=xxxxxxxxxxxxxxxxxxxxxx&grant_type=refresh_token]
Date: 2015-09-02 16:43
Status: 400
Content-Type: application/json
Size: 102 B
{
"error" : "invalid_request",
"error_description" : "Required parameter is missing: grant_type"
Is there a better way to do this? Maybe using RCurl? If so, what would the format of the request be? I would appreciate help on this!
The RAdwords package has a function to retrieve the refresh token. If you don't want to add the entire package you can just add the following code to your script.
refreshToken = function(google_auth) {
# This function refreshes the access token.
# The access token deprecates after one hour and has to updated
# with the refresh token.
#
# Args:
# access.token$refreh_token and credentials as input
# Returns:
# New access.token with corresponding time stamp
rt = rjson::fromJSON(RCurl::postForm('https://accounts.google.com/o/oauth2/token',
refresh_token=google_auth$access$refresh_token,
client_id=google_auth$credentials$c.id,
client_secret=google_auth$credentials$c.secret,
grant_type="refresh_token",
style="POST",
.opts = list(ssl.verifypeer = FALSE)))
access <- rt
access
}