Attribute provided with invalid value in Google Apps Script - http

Problem
I want to communicate with api while changing IP address, because the server restricts IP address. So, I add X-Forwarded-For header with UrlFetchApp. However, I get an error "Attribute provided with invalid value: Header:X-Forwarded-For
"
Question
How can I solve this problem? Or is there another way?
function myFetch() {
var url = "https://XXXXXXXXX"
var options = { method: "GET" };
options.headers = {
Authorization: "Bearer " + MY_TOKEN,
"X-Forwarded-For": "XXX.XXX.XXX.XXX"
};
var resp = UrlFetchApp.fetch(url, options);
var json = resp.getContentText();
var data = JSON.parse(json);
return data;
}
Tried → Error
Tried : cURL request.
→Success : I can change IP address, and get data.
curl -X GET \
https://XXXXXXXXX \
-H 'Authorization: Bearer MY_TOKEN' \
-H 'X-Forwarded-For: XXX.XXX.XXX.XXX' \
Tried : Delete X-Forwarded-For header.
→Error : "API key does not allow access from IP XXX.XXX.XXX.XXX"
Tried : I also add Host header.
→Error : "Attribute provided with invalid value: Header:Host".
Does anybody have a solution for my problem?
Best regards,

Related

Xamarin.Forms HttpClient send get request using a simple fourSquare API-KEY

I am trying to get a connection to the Places AIP of foursquare. (https://developer.foursquare.com/reference/place-search)
This needs me the send the following authorization header:
{ "Authorization" : "<API_KEY>"} and not { "Authorization" : "<SOME_SCHEMA> <API_KEY>"}
SOME_SCHEMA being "Basic", "Key" or any other type.
--header 'Authorization: API_KEY'
I tried to set is like so
client.DefaultRequestHeaders.Authorization = new
AuthenticationHeaderValue(Constants.API_KEY);
According to MSDN documentation this should work. but all I get is an exception saying that the header type is invalid..
Spend the day trying to found a way. but nothing I tried so far works.
I did text over curl and my api-key is good and so is the request. I really just need to get the HttpClient to accept not having a schema/type for Authorization.
This works.
it will allow to have a authorization header that does not contain an auth type.
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("Accept", "application/json");
request.Headers.TryAddWithoutValidation("Authorization", Constants.API_KEY);

oauth2 error AADSTS90014: The request body must contain the following parameter: 'grant_type'

From the development in Windev I use Oauth 2.0 for authorization to get access to the outlook mail from a user.
The application is registered at https://apps.dev.microsoft.com without the Implicit workflow.
After the user enters the credentials, an Authorization Code is returned.
With the new code the Bearer Token is requested with a HTTP Post command.
So far, so good.
Only that the response gives an error message that makes no sense to me.
In code:
m_sHTTPUrl = "client_id=" + m_sClientID + "&client_secret=" ...
+ m_sClientSecret ...
+ "&redirect_uri=" + m_sRedirectURL + "&code=" + m_sAuthToken ...
+ "&grant_type=authorization_code"
m_sHTTPres = ""
LogLocalFile("GetAccessToken - " + m_sTokenURL + " // " + m_sHTTPUrl)
cMyRequest is httpRequest
cMyRequest..Method = httpPost
cMyRequest..URL = m_sTokenURL
cMyRequest..ContentType = "application/x-www-form-urlencoded"
cMyRequest..Header["grant_type"] = "authorization_code"
cMyRequest..Header["code"] = m_sAuthToken
cMyRequest..Header["client_id"] = m_sClientID
cMyRequest..Header["client_secret"] = m_sClientSecret
cMyRequest..Header["scope"] = m_sScope
cMyRequest..Header["redirect_uri"] = m_sRedirectURL
//cMyRequest..Content = m_sHTTPUrl
cMyResponse is httpResponse = HTTPSend(cMyRequest)
m_sHTTPres = cMyResponse.Content
In a logfile I requested the used parameters and the content of the httpResponse:
GetAccessToken - https://login.microsoftonline.com/common/oauth2/v2.0/token // grant_type=authorization_code
&code=xxxxxxx
&scope=openid+offline_access+User.Read+Email+Mail.Read+Contacts.Read
&redirect_uri=http://localhost/
&client_id=xxxxxxx
&client_secret=xxxxxxx
GetAccessToken - error = invalid_request
GetAccessToken - error_description = AADSTS90014: The request body must contain the following parameter: 'grant_type'.
The grant_type is in the header as it is supposed to be.
Does anybody have any clue of what is needed to get the OAUTH2 working ?
You shouldn't send grant_type neither in params nor in headers. Those should be sent in body params then only it will work.
Url: https://login.microsoftonline.com/common/oauth2/v2.0/token
client_id, scope and redirect_uri params can be sent as query params.
where as grant_type, code and client_secret should sent in body params.
grant_type:authorization_code,
code: {code you got from the authorization step},
client_secret: ****
You need to pass everything in body as form-data:
curl --location --request POST 'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token' \
--form 'grant_type=authorization_code' \
--form '<the code you have got from the authorization endpoint' \
--form 'client_secret=****' \
--form 'client_id=********' \
--form 'scope=m_sScope' \
--form 'redirect_uri=http://localhost/'
you should change the content type as : application/x-www-form-urlencoded
the body must to be formated as bellow:
client_id=8cfbe8ac-8775-4c56-9302-k9d5a42cbf98
&client_secret=BOy7Q~pGvXF.SWshX72mmMnQeAkvN5elHWiYT
&grant_type=client_credentials
&resource=https://miurl.com
I finally got this right after referring to multiple answers.
POST https://login.microsoftonline.com//oauth2/token
--make sure to enter the ID directly without <,>
Use 'x-www-form-urlencoded' format for the Body.
Enter Keys & Values for the below parameters
client_id - Client_ID on your Azure App
client_secret - client_secret value and not the key. Note that this value is available only for the first time upon the client secret key creation
grant_type - client_credentials (static words, don't try to look for the value)
resource - App ID URI
reference link - https://learn.microsoft.com/en-us/previous-versions/azure/dn645543(v=azure.100)?redirectedfrom=MSDN
when providing "Default Scope" value must be full name example , "User.Read" correct value can get from azure AD APP -> Api Permission

unable to exchange auth token with access token - redirect uri missmatch

I try to build below:
by following: this steps
however, i keep receiving redirect uri missmatch when i tried to exchange auth code (given by my mobile app) to google server - which i couldn't understand because technically there is no redirect uri required for my flow case...
here are the details:
in Android Client:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
.requestServerAuthCode(serverClientId, false)
.build();
/**** bla.... ****/
GoogleSignInAccount acct = result.getSignInAccount();
String authCode = acct.getServerAuthCode();
/**** android app will send this authCode to my server ****/
/**** sample authCode: 4/Jny2Mxxx3x09sy4pqY3ZAwSTEz8rw2xxxxC-4VxxxxM
in my backend server:
try:
# i receive authCode correctly from android app.
# and use authCode to exchange to Access Token to google server as below:
credentials = client.credentials_from_clientsecrets_and_code(
app.config.get('GG_APP_SECRET'),
['https://www.googleapis.com/auth/plus.me', 'profile', 'email'],
authCode)
except Exception as e:
log.info('>>>>> I always receive: redirect uri missmatch here: %s <<<<<', e)
return generate_response(code=400, error=False, type='Fail', message=str(e))
this is curl from my backend server:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"authCode": "4/HP_cP_t70pgBrxxx7sjzCil7kaUHkxxxerdkMxxxrRg" \
}' 'http://localhost:5005/api/user/register/gg'
this is my console settings:
Questions:
is the serverClientId in android client suppose to be the clientID of above image?
what is the redirect uri that i should put in google console above?
what should i set/configure for my redirect uri? or is there any specific settings that i need to do?
Ok I go it,
if you see this
you will found out:
def credentials_from_clientsecrets_and_code(filename, scope, code,
message=None,
redirect_uri='postmessage',
http=None,
cache=None,
device_uri=None):
and you realize that redirect_uri = 'postmessage' which in my case i dont have post message.
so what i do is to match that redirect_uri with authorize redirect uri that i have in google console
so for my case in my question above, i change my python code to:
credentials = client.credentials_from_clientsecrets_and_code(
app.config.get('GG_APP_SECRET'),
['https://www.googleapis.com/auth/plus.me', 'profile', 'email'],
authCode, redirect_uri='https://developers.google.com/oauthplayground')

Convert cURL to Google Apps Script

I am trying to convert a cURL command to a Google Apps Script PUT request.
I came up with the below google script but it does not seem to work. When I change the URL of both of these to RequestBin in order to probe what the server side is getting, RequestBin shows that the raw source of both of these come through as exactly the same. Yet, only the cURL command is able to perform the desired action (update a file on github) when I change it back to the github URL.
curl -i -X PUT -H 'Authorization: token yadayda' -d '{"path":"mygeojson.json","message":"Initial Commit","committer":{"name":"Sidd","email":"siddsubra#gmail.com"},"content":"bXkgbmV3IGZpbGUgY29udGVudHM=","sha":"0d5a690c8fad5e605a6e8766295d9d459d65de42","branch":"master"}' https://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json
cURL Command
And this is the Google Script
function mainscript() {
var sha = getSHA();
var authenticationToken = "yadayada";
var url = "http://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json";
var headers = {
"Authorization" : "token " + authenticationToken,
};
var payload = {
"path": "mygeojson.json",
"message": "Initial Commit",
"committer":{
"name": "Sidd",
"email": "siddsubra#gmail.com"
},
"content": "bXkgbmV3IGZpbGUgY29udGVudHM=",
"sha": sha,
"branch": "master"
};
var options = {
"headers" : headers,
"method" : "PUT",
"payload" : JSON.stringify(payload)
};
Logger.log(options);
Logger.log(UrlFetchApp.fetch(url, options));
}
Google Apps Script
I recently did a script that call a request to a API from scrapy cloud, and had a dificulty to convert curl to App Script request too.
I noticed that payload doesn't worked when i used JSON.stringify, so try remove it from payload:
"payload" : payload
Other observation was the need to use Utilities.base64Encode in authentication token:
headers = {"Authorization":"Basic " + Utilities.base64Encode(authenticationToken + ":" + "")}
See this sample:
url = "https://app.scrapinghub.com/api/run.json"
headers = {"Authorization":"Basic " + Utilities.base64Encode("myToken" + ":" + "")}
payload = {"project":"327107", "spider":"pmp"}
options = {"headers":headers, "payload":payload}
response = UrlFetchApp.fetch(url, options)
data = JSON.parse(response.getContentText())

Put a custom http header in backbone

I am creating an API with Tastypie and I want to access to the API from Backbone.
To send credentials I use an user_id and a api_key. I do this in android and with curl and this work great, but I can set the http header from backbone.
In curl I use:
curl --dump-header - -H "Accept: application/json" -H "Content-Type: application/json" -H "user_id: 32" -H "api_key: 69950" -X DELETE "http://127.0.0.1:8000/api/v1/deletenote/66/?format=json"
and in android java I use:
HttpDelete requestDELETE = new HttpDelete();
requestDELETE.setHeader("Content-type", "application/json");
requestDELETE.setHeader("Accept", "application/json");
requestDELETE.setHeader(Constants.HEADER_USER_ID, user_id);
requestDELETE.addHeader(Constants.HEADER_API_KEY, key);
Both of them work great, but when I try this in Backbone following the responses that I found in other post from the page, this didn't work.
I am trying this:
var removeNote = new DeleteNoteModel({id:this.model.toJSON().id},{ query:this.model.toJSON().id});
removeNote.destroy({
headers: {'user_id':dataWeb.get("id"),'api_key':dataWeb.get("api_key")}
},{
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
}
);
I'm putting the header when I call to the destroy call, but this don't send anithing to the server.
What I am doing in a wrong mode?
Thanks to all.
Tallmaris answer should fix it for you though I would recommend usign jQuery ajaxSetup method to setup the headers as default values for all ajax requests as I believe you need them all the time anyway right?
Somewhere where you launch the App put in
$.ajaxSetup({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}
});
Thanks to that you'll save yourself a lot of repeated code :) keep it DRY!
(obviously you'd need to ensure that dataWeb is available in the scope of where you launch the app :) )
It seems you are passing two parameters to destroy, pass only one containing the headers and the other options together, unless the brackets order is a typo. Try this:
removeNote.destroy({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}, // there was an extra close-open curly here...
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
});

Resources