Google OAuth Code Contains Hashtag - coldfusion

In my attempts to get the necessary code so I can generate my refresh token, I ran this URL:
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/drive.file&redirect_uri=--mywebsite--&response_type=code&client_id=--myclientid--
And my received code contains a trailing hash tag, which throws an (expected) error when I try to execute:
<cfhttp url="https://accounts.google.com/o/oauth2/token" method="post">
<cfhttpparam name="code" value="4/UXF5F5TlIuFsXrav-DvIrebMR8NST9WK-EPmThmx7l0#" type="formfield"> <!-- Sample code value -->
<cfhttpparam name="client_id" value="--myclientid--" type="formfield">
<cfhttpparam name="client_secret" value="[client secret]" type="formfield">
<cfhttpparam name="redirect_uri" value="--mywebsite--">
<cfhttpparam name="grant_type" value="authorization_code" type="formfield">
</cfhttp>
ColdFusion was looking at the following text:formfieldThe CFML compiler was processing:An expression that began on line 2, column 86.The expression might be missing an ending #, for example, #expr instead of #expr#.The tag attribute value, on line 2, column 34.A cfhttpparam tag beginning on line 2, column 10.
I tried adding a second hashtag to make it literal but I receive { "error" : "invalid_grant", "error_description" : "Invalid code." } response.
Am I missing something painfully obvious here? The tutorial I was following is at http://www.brandiandjohn.com/post.cfm/oauth-2-google-and-cfml-without-cfoauth

In order to continue with the existing code, you need to escape #. You can do that, by adding an extra # at the end. For eg
<!---
<cfset value="4/UXF5F5TlIuFsXrav-DvIrebMR8NST9WK-EPmThmx7l0#">
<cfoutput>#value#</cfoutput>
Error
--->
<cfset value="4/UXF5F5TlIuFsXrav-DvIrebMR8NST9WK-EPmThmx7l0##">
<cfoutput>#value#</cfoutput>
Output: 4/UXF5F5TlIuFsXrav-DvIrebMR8NST9WK-EPmThmx7l0#
So, you can try the below code:-
<cfhttp url="https://accounts.google.com/o/oauth2/token" method="post">
<cfhttpparam name="code" value="4/UXF5F5TlIuFsXrav-DvIrebMR8NST9WK-EPmThmx7l0##" type="formfield"> <!-- Sample code value -->
<cfhttpparam name="client_id" value="--myclientid--" type="formfield">
<cfhttpparam name="client_secret" value="[client secret]" type="formfield">
<cfhttpparam name="redirect_uri" value="--mywebsite--">
<cfhttpparam name="grant_type" value="authorization_code" type="formfield">
</cfhttp>

The hashtag error was a red herring. I got around this by making the call to get the code and then the access token as a single action. By passing in url.code I received the necessary credentials.
<cfhttp url="https://accounts.google.com/o/oauth2/token" method="post">
<cfhttpparam name="code" value="#url.code#" type="formfield">
<cfhttpparam name="client_id" value="--myclientid--" type="formfield">
<cfhttpparam name="client_secret" value="[client secret]" type="formfield">
<cfhttpparam name="redirect_uri" value="--mywebsite--">
<cfhttpparam name="grant_type" value="authorization_code" type="formfield">
</cfhttp>
<cfdump var="#foo.filecontent#">
Manually pasting the code into the cfhttpparam tag, even without the hashtag, would throw a 400 error. This way, it does not.

The user agent that sent you the code should have stripped the "#" character, see: Google OAuth service redirects to URL with a # sign at the end. Apparently it did not (and as such that user agent is broken) but you can strip it manually in your code before sending if off.

Related

EZ Text API & ColdFusion

Anyone have any experience with the EZ Text API and ColdFusion? I'm trying this call:
<cfhttp url="https://app.eztexting.com/sending/messages?format=JSON"
method="POST" result="objGet" charset="utf-8">
<cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded">
<cfhttpparam type="formfield" name="User" value="xxx" />
<cfhttpparam type="formfield" name="Password" value="xxx"/>
<cfhttpparam type="formfield" name="PhoneNumbers[]" value="9999999999" />
<cfhttpparam type="formfield" name="MessageTypeID" value="1" />
<cfhttpparam type="formfield" name="Message" value="Hello" />
</cfhttp>
... which is returning a status code of 200 and trying to redirect to their home page.
Their tech support can only tell me that I should use curl which is not installed on the server that I need it on. I have used curl successfully in my devel environment, so I'm sure that the url and credentials are good.
Any thoughts are welcome! Thanks.
I'm guessing you're using the REST API. If yes, the reason it's redirecting you to the home page is because the URL is incorrect. Apparently the format parameter is case sensitive. So ?format=JSON should be changed to ?format=json (all lower case).
Making that minor adjustment to your code example:
<cfhttp url="https://app.eztexting.com/sending/messages?format=json"
method="POST" result="objGet" charset="utf-8">
...
</cfhttp>
... returns the expected JSON response for bogus credentials, instead of the html for the home page:
{
"Response": {
"Status": "Failure",
"Code": 401,
"Errors": [
"Authorization Required"
]
}
}
Once you get past this issue, you may want to double check your formfield names. The API lists the parameter name PhoneNumbers, not PhoneNumbers[].

Windows Push Notification Services Token request via ColdFusion

I am trying to get the "access token" from WNS via a ColdFusion request but I get a "Bad Request" response. I believe I have everything set up correctly following the instructions here. My devices are registering the URI's to my backend.
Here is a simple code snippet;
(I've hidden the secret key of course)
<cfhttp url="https://login.live.com/accesstoken.srf" method="post" result="httpResp">
<cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded" />
<cfhttpparam type="URL" name="grant_type" value="client_credentials" />
<cfhttpparam type="URL" name="client_id" value="ms%2Dapp%3A%2F%2Fs%2D1%2D15%2D2%2D1197233413%2D3602308102%2D1084427847%2D2188608249%2D1036687727%2D3580410356%2D2392468796" />
<cfhttpparam type="URL" name="client_secret" value="************************" />
<cfhttpparam type="URL" name="scope" value="notify.windows.com" />
I am also getting failed response when I test the URL directly via the browser. Appreciate your help.
Thank you,
Ian.
I think your cfhttpparam fields now set to "URL" should actually be set to "FORMFIELD" based on the example on MSDN.
<cfhttpparam type="FORMFIELD" name="grant_type" value="client_credentials" />
<cfhttpparam type="FORMFIELD" name="client_id" value="..." />
<cfhttpparam type="FORMFIELD" name="client_secret" value="************************" />
<cfhttpparam type="FORMFIELD" name="scope" value="notify.windows.com" />
The example appears to put thes in the content area (showing a raw post) - so these are form fields of a post, not URL fields right?

Need Help for ColdFusion SessionToken and AIM for Authorize.net

I am trying to solve a problem that occurs with Authorize.net. The SessionToken is generated while in test mode through a test account. Now, a new SessionToken is generated each time the form is previewed through the test account or the actual account.
A hidden input field is shown each time when the form is accessed in preview mode. I have generated a hidden input field on my form by using a toBase64() string combined from the x_login and the x_tran_key. The output is this:
<INPUT TYPE="HIDDEN" NAME="SessionToken" ID="SessionToken" VALUE="TXpOSFRUWXpXbk40VjNSeg==TlRsU2JqaHFOM2RLZFd0RU5VdzJadz09">
in the forms hidden input field for SessionToken as you can see above.
When generating my own SessionToken for processing, the error shown after trying to process the https://test.authorize.net/gateway/transact.dll shows this:
(46) Your session has expired or does not exist. You must log in again
to continue working.
The only way for the form to actually work is after grabbing the SessionToken code from the form in preview mode. For example: Go to Account --> Settings --> Payment Form --> Preview --> and viewing and copying the code from view frame source. It looks like this:
<INPUT TYPE="HIDDEN" NAME="SessionToken" ID="SessionToken" VALUE="jMsCez2DId$VvgF4s4Hbjbe$Uv6WnJh8cEKBD5HqTUEqlHoRBebKZ07bp4RZdpwOPnGabB3pbcWFppJCph7dg6HjQeroJvlay6mQm5ocjkZPq44uT4nqeg2zWhX13b7Blp$qN7ZDzQ5HF1abfukJTQAA,jMsCez2DId$VvgF4s4Hbjbe$Uv6WnJh8cEKBD5HqTUEqlHoRBebKZ07bp4RZdpwOPnGabB3pbcWFppJCph7dg6HjQeroJvlay6mQm5ocjkZPq44uT4nqeg2zWhX13b7Blp$qN7ZDzQ5HF1abfukJTQAA">
Finally, if I use the value:
jMsCez2DId$VvgF4s4Hbjbe$Uv6WnJh8cEKBD5HqTUEqlHoRBebKZ07bp4RZdpwOPnGabB3pbcWFppJCph7dg6HjQeroJvlay6mQm5ocjkZPq44uT4nqeg2zWhX13b7Blp$qN7ZDzQ5HF1abfukJTQAA
as the SessionToken as:
<cfset SessionToken = 'jMsCez2DId$VvgF4s4Hbjbe$Uv6WnJh8cEKBD5HqTUEqlHoRBebKZ07bp4RZdpwOPnGabB3pbcWFppJCph7dg6HjQeroJvlay6mQm5ocjkZPq44uT4nqeg2zWhX13b7Blp$qN7ZDzQ5HF1abfukJTQAA'>
and process the form it works. But it only works one time for the current session if signed into the Test Account.
All help is appreciated of course. This is the last part to the code I need and just can not figure out how to make it work. I need to fetch the response for the SessionToken to populate the SessionToken hidden field input on the form.
I am not using the CFHTTP method because the form is on the website and when the payment form loads the SessionToken is needed. Meaning that the submit/sending... button on the form is submitted it then processes the payment and displays the receipt.
If you download the Coldfusion sample code from Authorize.net you will notice you do not need a SessionToken. See below:
Source: http://developer.authorize.net/downloads/samplecode/
<cfhttp method="Post" url="https://test.authorize.net/gateway/transact.dll">
<!--- the API Login ID and Transaction Key must be replaced with valid values --->
<cfhttpparam type="Formfield" name="x_login" value="API_LOGIN_ID">
<cfhttpparam type="Formfield" name="x_tran_key" value="TRANSACTION_KEY">
<cfhttpparam type="Formfield" name="x_delim_data" value="TRUE">
<cfhttpparam type="Formfield" name="x_delim_char" value="|">
<cfhttpparam type="Formfield" name="x_relay_response" value="FALSE">
<cfhttpparam type="Formfield" name="x_type" value="AUTH_CAPTURE">
<cfhttpparam type="Formfield" name="x_method" value="CC">
<cfhttpparam type="Formfield" name="x_card_num" value="4111111111111111">
<cfhttpparam type="Formfield" name="x_exp_date" value="0115">
<cfhttpparam type="Formfield" name="x_amount" value="19.99">
<cfhttpparam type="Formfield" name="x_description" value="Sample Transaction">
<cfhttpparam type="Formfield" name="x_first_name" value="John">
<cfhttpparam type="Formfield" name="x_last_name" value="Doe">
<cfhttpparam type="Formfield" name="x_address" value="1234 Street">
<cfhttpparam type="Formfield" name="x_state" value="WA">
<cfhttpparam type="Formfield" name="x_zip" value="98004">
<!--- Additional fields can be added here as outlined in the AIM integration
guide at: http://developer.authorize.net --->
<!--- The following fields show an example of how to include line item details, they are commented out by default.
<cfhttpparam type="Formfield" name="x_line_item" value="item1<|>golf balls<|><|>2<|>18.95<|>Y">
<cfhttpparam type="Formfield" name="x_line_item" value="item2<|>golf bag<|>Wilson golf carry bag, red<|>1<|>39.99<|>Y">
<cfhttpparam type="Formfield" name="x_line_item" value="item3<|>book<|>Golf for Dummies<|>1<|>21.99<|>Y">
--->
</cfhttp>
Hope this helps.

google analytics, hitting it from coldfusion server cfhttp

I have used this:
Generate Google Analytics events (__utm.gif requests) serverside
and this:
http://www.garyrgilbert.com/blog/index.cfm/2008/10/21/Tracking-Digital-Content
to build a cfhttp string so that when a user hits a page it calls google analytics. I'm doing it like this because the pages I'm serving are XML pages and I can't mix javascript with xml.
My problem is that google analytics is ignoring my requests. I have activated my bucket code on a normal html server, so it thinks/knows it exists, but now when i call any of my xml server pages and make the cfhttp request from coldfusion server, it doesn't get registered.
Update:
Following Sergii advice, I have done a dump to find out what the cfhttp is doing (i was previously missing a variable which was causing it to error), i am now getting a http return of 200, though analytics is not applying the request to my account.
Update the 2nd, including code:
<cfset var_utmac='UA-myUA'> <!--- enter the new urchin code --->
<cfset var_utmhn='www.myaddress.co.uk'>
<cfset var_utmn = RandRange(10000000,99999999)>
<cfset var_cookie = RandRange(10000000,99999999)>
<cfset var_random = RandRange(1000000000,2147483647)>
<cfset var_today = now()>
<cfset var_referer = #cgi.HTTP_REFERER#>
<cfset var_uservar = 'jevans'>
<cfset var_utmp= ''>
<cfset apiname = 'listings.getlistings'>
<cfhttp method="get" url="http://www.google-analytics.com/__utm.gif">
<cfhttpparam type="url" name="utmwv" value="1" />
<cfhttpparam type="url" name="utmn" value="#var_utmn#" />
<cfhttpparam type="url" name="utmsr" value="-" />
<cfhttpparam type="url" name="utmsc" value="-" />
<cfhttpparam type="url" name="utmul" value="-" />
<cfhttpparam type="url" name="utmje" value="0" />
<cfhttpparam type="url" name="utmfl" value="-" />
<cfhttpparam type="url" name="utmdt" value="#apiName#" />
<cfhttpparam type="url" name="utmhn" value="#var_utmhn#" />
<cfhttpparam type="url" name="utmr" value="#var_referer#" />
<cfhttpparam type="url" name="utmp" value="#var_utmp#" />
<cfhttpparam type="url" name="utmac" value="#var_utmac#" />
<cfhttpparam type="url" name="utmcc" value="__utma%3D#var_cookie#.#var_random#.#var_today#.#var_today#.#var_today#.2%3B%2B__utmb%3D#var_cookie#%3B%2B__utmc%3D#var_cookie#%3B%2B__utmz%3D#var_cookie#.#var_today#.2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D#var_cookie#.#var_uservar#%3B" />
</cfhttp>
any thoughts?
cheers
Looking at your code, I'm guessing that you need to replace &amp's in your code with regular & symbols. You only need to escape the ampersands to validate XML documents and such. If you send them over the URL, then they may not be recognized as separators.
I would actually construct it like so:
<cfhttp method="get" url="http://www.google-analytics.com/__utm.gif">
<cfhttpparam type="url" name="utmwv" value="5.1.2" />
<cfhttpparam type="url" name="utmn" value="#var_utmn#" />
... all your other URL variables
<cfhttp>
This will make your code a little easier to read, as well as make sure that all of your variables are sent over in the property format, without needing to concatenate a huge string.
It looks like several of your parameters should be of different types. You are sending them all as URL parameters. Should, for example, the HTTP_REFERER be sent as type="CGI".
Looking at my own GA HTTP, I see that in my URL string that I have utmr=-
But the request is also sending along a CGI header for Referer: http://12robots.com/
Maybe try adding another param with type="CGI" name="HTTP_REFERER" value="#CGI.HTTP_REFERER#"
You might want to look at how it is being done in this PHP class and see if you can adapt it to your ColdFusion code. It looks like it might be more than a few URl params that need setting. It is likely that you need to better simulate a real browser to make GA think you are a real browser.
http://code.google.com/p/serversidegoogleanalytics/
Pretty sure cfset var_today = now() is wrong. GA has no idea what a ColdFusion date/time object is

Syncing database with google fusion table

I am having troubles figuring out the google api.. I am trying to insert data into my fusion table via my coldfusion application..
<cfhttp url="https://www.google.com/accounts/ClientLogin" method="post" charset="utf-8">
<cfhttpparam type="formfield" name="accountType" value="GOOGLE"></cfhttpparam>
<cfhttpparam type="formfield" name="Email" value="MYUSERNAME"></cfhttpparam>
<cfhttpparam type="formfield" name="Passwd" value="MY PASSWORD"></cfhttpparam>
<cfhttpparam type="formfield" name="accountType" value="GOOGLE"></cfhttpparam>
<cfhttpparam type="formfield" name="service" value="fusiontables"></cfhttpparam>
</cfhttp>
this comes back with
SID=DQAAALoAAAC5eSJUrVB_WVchS1plunfW2YPUTadHAxoEbE0xMcOzQxeTloc2RWWBjoJi4jKm6NIiFbGbV_IQ3vuY9bl-Z0RS64OFAy5aUY-Do_nX8DpPhVkEyBzDScJidi73G7ZqWmkdykkIGCBrr7MLa-eBMrXZvLJP0D21xJTjxRWyeM4xuEMQGhEbnWwBL9RnEByr5Rsgzx7dl9n4tsYQOvaGV3ZcMlT0CooS2__orwC12UH7eKCk-REKzbX5Z-bbu4EdLps LSID=DQAAALwAAABV7lz-YRh02pR7IlWkKidScbYTQArBWnaAJpAlZQ9rgtgmdQCSBuIZQQ21QDXZLORwTAyDi-34Mjs8SKvI7ronBSuniDW2SGipYoUhZDEjxwR55DQc1AaI3JgGPMc69YGAVv-_EMwXlS7elWO6lDW-G4PTR6Aqa0DO3y7Iig-L7g2b7zMFq32JIvjUj5rofcykF27T8sOuhd0Z4XTvgO-18Kp2z8o6EK_5qjZcHPmih0GB6LeSElBo2wjah1TM2u0 Auth=DQAAALwAAADYQbciaOLab2Aw_QghTO8hR0DPDOjoWZVKeJ-ApGwoUz7OgcqVtSHMUvRHHZoKys5ygjhm2FiHSh1CvW1SicOvajwRZSstvghtsCQl-y7LeT8TMkeCj5ZIqy8A05wg1YjCz3F3eDz9TImtlvGij7IOdWJ3Ae4NE8WQdC0Js5Laccebhgjj7Lk9FkRgG9c3yRyGhu7LmsRbtLjfv5jwGoozDuCcx6b79bECoR8qABkT-e5HgF7sWjYbLfz667OCeA0
Now I am trying to insert into my table... I am passing the auth value from above.. I can not find anywhere in the google docs what the authentication fields should be.. any help would be greatly appreciated..
<cfhttp url="https://www.google.com/fusiontables/api/query" method="post" charset="utf-8">
<cfhttpparam type="formfield" name="sql" value="INSERT INTO 423555 (id, outcode,lat,lng) VALUES ('1','W14',1231232,-123123);"/>
<cfhttpparam type="header" name="Authorization" value="Auth"></cfhttpparam>
<cfhttpparam type="header" name="token" value="#listtoarray(cfhttp.FileContent,"=")[4]#"></cfhttpparam>
</cfhttp>
The AUTH should be the auth token you received in google's response.
From the docs you should make a header like:
Authorization: GoogleLogin auth=yourAuthToken
So, this would be
<cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#listtoarray(cfhttp.FileContent,"=")[4]#"></cfhttpparam>
This is assuming the #listtoarray(cfhttp.FileContent,"=")[4]# returns the value of the Auth property - I haven't counted it out to be sure.
I don't think, just glancing at the docs, the "token" header is needed.
But, #listtoarray(cfhttp.FileContent,"=")[4]# is a really fragile way of doing it. If Google were to reorder their response or change it, your code wouldn't work any more.
I would look to a more robust way of parsing the response. I would probably split the response on whitespace and turn it into a struct with the names as keys, then you could use something like
#response['auth']#