Re: [WebDNA] YouTube API v2.0 - OAuth 2.0 Authorization

This WebDNA talk-list message is from

2013


It keeps the original formatting.
numero = 110550
interpreted = N
texte = --20cf30223ab542cd1904e35c7460 Content-Type: text/plain; charset=ISO-8859-1 Thank you!!!! That's awesome. That did it. I just had to change one variable. I can't spend more time on it until later today/night, but this worked for me perfectly!! The key, that I was missing, was the content length and connection close. Though I think it is specifically the content length that did the trick. Thanks again!! d. [text]crlf=[unurl]%0D%0A[/unurl][/text][!] [/!][text]dataString=code=[_code]&[!] [/!]client_id=[client_id]&[!] [/!]client_secret=[client_secret]&[!] [/!]redirect_uri=[redirect_uri]&[!] [/!]grant_type=authorization_code[/text][!] [/!][text]auth_response=[!] [/!][TCPconnect host=accounts.google.com&SSL=T&port=443][!] [/!][TCPsend skipheader=T]POST /o/oauth2/token HTTP/1.1[crlf][!] [/!]Host: accounts.google.com[crlf][!] [/!]Content-Type: application/x-www-form-urlencoded[crlf][!] [/!]Content-Length: [countchars][dataString][/countChars][crlf][!] [/!]Connection: close[crlf][!] [/!][crlf][!] [/!][dataString][crlf][!] [/!][/TCPSend][!] [/!][/TCPconnect][/text][!] [/!] auth_response: [auth_response] On Wed, Aug 7, 2013 at 3:09 AM, wrote: > okay, I can't guarantee that this is 100% working code. I had to dig back > to some old code I wrote a couple years ago to connect to Google Calendar > feeds via Oauth2. Amidst the code I found were versions leading up to this > that didn't work great. Also, this isn't dainty but I remember whatever I > ended up did work. In any case you should be able to get something from > it... and maybe a little more. > > The Oauth2 process is a multistep process. The first step is sending some > info to a google url where the user can authorize access which will then > send back a temporary token to the redirect uri you specify. This temp > token is used to create the real deal tokens you'll be getting with the > tcpsend > > Here's how I mostly remember doing it... (I used a bit of javascript and > ajax to move the information around nicely) > > #1 --> I stored my api creds in a database. The first page populates a > form with that info that then opens a popup window (the initial google > access url). > #2 --> the redirect URI I specified also has some javascript that sends > the response w/ token back to another form on the initial page. Then, that > form is submitted via ajax to another google authorization dna script. > #3 --> The final tokens retrieved from the ajax call are stored into > another database to be used for further api requests during the session. > > I'm not going to deconstruct everything, but you should get the gist by > reviewing the code. > > so here it is... > > > THE STARTING PAGE > > > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> > > > > > Google Data API Access > > > [!]INCLUDE A JQUERY JS FILE HERE[/!] > > > > > > > > > > > > > [function name=urlEncode] > [grep search=[url]\.[/url]&replace=[url]%2E[/url]][grep > search=[url]\/[/url]&replace=[url]%2F[/url]] > [stringIn][/grep][/grep] > [/function] > >
> > [search db=[dir]dbs/cells/googleDataAPI.db&eqIDdatarq=1] > [founditems] > > > > > [/founditems] > [/search] > >
> > > > >
> > [search db=[dir]dbs/cells/googleDataAPI.db&eqIDdatarq=1] > [founditems] > > > [/founditems] > [/search] > > > >
> > > > > > > > > > > NEXT, THE CODE CONTAINED IN THE RETURN URI > > > > > > [!]OR WHEREVER YOUR JQUERY FILE IS[/!] > > > > > > > > [formvariables] > [showif [name]=code] > > [value] > [/showif] > > [/formvariables] > > > > > > > LAST, THE FINAL CALL TO GET API TOKENS, WHICH ARE STORED IN DB FOR SESSION > USE ( grabAPIToken.dna ) > > > > > [text]crlf=[unurl]%0D%0A[/unurl][/text][!] > [/!][text]dataString=code=[_code]&[!] > [/!]client_id=[client_id]&[!] > [/!]client_secret=[client_secret]&[!] > [/!]redirect_uri=[redirect_uri]&[!] > [/!]grant_type=[grant_type][/text][!] > [/!][text]auth_response=[!] > [/!][TCPconnect host=accounts.google.com&SSL=T&port=443][!] > [/!][TCPsend skipheader=T]POST /o/oauth2/token HTTP/1.1[crlf][!] > [/!]Host: accounts.google.com[crlf][!] > [/!]Content-Type: application/x-www-form-urlencoded[crlf][!] > [/!]Content-Length: [countchars][dataString][/countChars][crlf][!] > [/!]Connection: close[crlf][!] > [/!][crlf][!] > [/!][dataString][crlf][!] > [/!][/TCPSend][!] > [/!][/TCPconnect][/text][!] > [/!] > > > > [!] A HACKY WAY OF GETTING THE JSON DATA INSTEAD OF USING JAVASCRIPT [/!] > [text]thestr=[getchars > start=1&end=&trim=left][auth_response][/getchars][/text] > > [text]thestr=[grep search=\{&replace=][grep > search=\}&replace=][thestr][/grep][/grep][/text] > > [listwords words=[thestr]&delimiters=,][!] > [/!][text][listwords words=[grep > search=\"&replace=][word][/grep]&delimiters=:][word][showif > [index]=1]=[/showif][/listwords][/text][!] > [/!][/listwords] > [!] A HACKY WAY OF GETTING THE JSON DATA INSTEAD OF USING JAVASCRIPT [/!] > > > > [if ("[error]"!"[raw][error][/raw]")] > [then]ALERT THERE IS AN ERROR[/then] > [else] > > [!]IF SUCCESSFUL YOU WILL GET - ACCESS_TOKEN AND REFRESH_TOKEN VALUES[/!] > > [replace > db=[dir]dbs/cells/gDataConnects.db&eqFIELD1datarq=[thisUser]&eqFIELD2datarq=[_scope]&append=T&autonumber=ID][!] > > [/!]field1=[thisUser]&field2=[_scope]&field3=[date]&field4=[time]&field5=[access_token]&field6=[refresh_token][!] > [/!][text]streamID=[thisautonumber][/text][/replace] > [if ("[streamID]"="") | ("[streamID]"="[raw][streamID][/raw]")] > [then][search > db=[dir]dbs/cells/gDataConnects.db&eqFIELD1datarq=[thisUser]&eqFIELD2datarq=[_scope]&max=1][founditems][id][/founditems][/search][/then] > [else][streamID][/else] > [/if] > > > [/else] > [/if] > > > > A COUPLE FINAL NOTES... > > 1) if you use the POST method, your parameters should be sent in the body, > not in the url. Otherwise that is a GET request. > 2) if you use HTTP 1.1, you need to include in the headers.. > > Connection: close > > so the connection is not persistent > > > > > I put the hours in on this, and I don't even use it now. So hopefully > others can glean something from it. Hopefully it works out for you. > > > > On Aug 6, 2013, at 11:35 PM, David Bastedo wrote: > > Hi, > > I can't seem to make this work and I am hoping somebody can help or point > me in the right direction. > > I can get to step 4 but have been unable to exchange the authorization > code for an access token. > > I've tried a couple of variations of Tom's twitter code, but I just get > hung up - which I have read is because of HTTP/1.1 vs. 1.0 and the > expectation of a persistent connection. > > To get the authorization code, I just built a link: > > [text]debug=T[/text] > [text]client_id=XXXXX[/text] > [text]redirect_uri=XXXXX[/text] > [text]client_secret=XXXX[/text] > [text]theScope=https://www.googleapis.com/auth/youtube.readonly[/text] > > Ask > > > which gets me to > > [showif [state]=2] > > code: [code]
> > --> insert failed code here to get json response > > [/showif] > > I have tried multiple variations of: > > > [/!][text]content=grant_type=authorization_code[/text][!] > > [/!][text]jsonResponse=[TCPConnect host=accounts.google.com > &port=443&ssl=T][!] > [/!][tcpsend skipheader=F]POST /o/oauth2/token?code=[code]&[!] > [/!]client_id=[client_id]&[!] > [/!]client_secret=[client_secret]&[!] > [/!]redirect_uri=[redirect_uri]&grant_type=authorization_code > HTTP/1.1[CRLF][!] > [/!]Host: accounts.google.com[CRLF][!] > [/!]Content-type: application/x-www-form-urlencoded[CRLF][!] > [/!][/tcpsend][/tcpconnect][/text][!] > > ## debug info ## > [/!][showif [debug]=T]

OAuth Json Response

>
[jsonResponse]
[/showif][!] > > > > Tom's version for twitter worked perfectly but the YT format is different. > > link: > https://developers.google.com/youtube/2.0/developers_guide_protocol_oauth2#OAuth2_Server_Side_Web_Applications_Flow > > thanks in advance!! > > d. > --------------------------------------------------------- This message > is sent to you because you are subscribed to the mailing list **. To > unsubscribe, E-mail to: ** archives: > http://mail.webdna.us/list/talk@webdna.us Bug Reporting: support@webdna.us > **** > > > --------------------------------------------------------- This message is > sent to you because you are subscribed to the mailing list **. To > unsubscribe, E-mail to: ** archives: > http://mail.webdna.us/list/talk@webdna.us Bug Reporting: support@webdna.us -- David Bastedo Ten Plus One Communications Inc. http://www.10plus1.com 416.277.4499 --20cf30223ab542cd1904e35c7460 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Thank you!!!! That's awesome.

That did it. I just had to change one variable. I can't spend more = time on it until later today/night, but this worked for me perfectly!!

The key, that I was missing, was the content length and connectio= n close. Though I think it is specifically the content length that did the = trick.

Thanks again!!

d.

[text]crlf=3D[unurl]%0D%0A[/unurl][/text][!]
[/!][text]dataStri= ng=3Dcode=3D[_code]&[!]
[/!]client_id=3D[client_id]&[!]
[/!]c= lient_secret=3D[client_secret]&[!]
[/!]redirect_uri=3D[redirect_uri]= &[!]
[/!]grant_type=3Dauthorization_code[/text][!]
[/!][text]auth_response=3D= [!]
=A0=A0=A0 [/!][TCPconnect host=3Daccounts.google.com&SSL=3DT&port=3D443][!]
=A0=A0=A0 [/!= ][TCPsend skipheader=3DT]POST /o/oauth2/token HTTP/1.1[crlf][!]=A0=A0=A0 =A0=A0=A0 [/!]Host: accounts.google.= com[crlf][!]
=A0=A0=A0 [/!]Content-Type: application/x-www-form-urle= ncoded[crlf][!]
=A0=A0=A0 [/!]Content-Length: [countchars][dataString][/= countChars][crlf][!]
=A0=A0=A0 [/!]Connection: close[crlf][!]
[/!][crlf][!]
=A0=A0=A0 [/!]= [dataString][crlf][!]
=A0=A0=A0 [/!][/TCPSend][!]
=A0=A0=A0 [/!][/TCP= connect][/text][!]
[/!]

auth_response: [auth_response]
<= /div>


On Wed, Aug 7, 2013 at 3:09 AM, <aaronmichaelmusic@gmail.com> wrote:
okay, I can't guarantee that this i= s 100% working code. =A0I had to dig back to some old code I wrote a couple= years ago to connect to Google Calendar feeds via Oauth2. =A0Amidst the co= de I found were versions leading up to this that didn't work great. =A0= Also, this isn't dainty but I remember whatever I ended up did work. = =A0In any case you should be able to get something from it... and maybe a l= ittle more.

The Oauth2 process is a multistep process. =A0The first step= is sending some info to a google url where the user can authorize access w= hich will then send back a temporary token to the redirect uri you specify.= =A0This temp token is used to create the real deal tokens you'll be ge= tting with the tcpsend

Here's how I mostly remember doing it... (I used a = bit of javascript and ajax to move the information around nicely)

#1 --> I stored my api creds in a database. =A0The first= page populates a form with that info that then opens a popup window (the i= nitial google access url). =A0
#2 --> the redirect URI I specified also has some javascript that s= ends the response w/ token back to another form on the initial page. =A0The= n, that form is submitted via ajax to another google authorization dna scri= pt. =A0
#3 --> The final tokens retrieved from the ajax call are stored int= o another database to be used for further api requests during the session.<= /div>

I'm not going to deconstruct everything, but y= ou should get the gist by reviewing the code.

so here it is...


THE STARTING PAGE


<!DOCTY= PE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<html xmlns=3D"http://www.w3.org/1999/xhtml"= ; xml:lang=3D"en-us">

<head>
<meta charset=3D"utf-8&q= uot; />
<title>Google Data API Access</title>


[!]INCLUDE A JQUERY JS FILE HERE[/!]

<script type=3D"text/javascript">
=

//final ajax call to get access tokens
functi= on grabToken() {

$.ajax({
type: "POST",
cache: false,
url: "grabAPIToken.dna",
data: $("#grabToken").serializeArray(),
success: function(data) = {
//redirect to ano= ther page or do something here
alert('you did it');
}
});
}

= //redirect uri calls to this function
function getTempToken(theCo= de) {
$("#backCode").val(theCode);
grabToken();
}

//starting point
function startAPIAc= ess() {
$("#APIstart").submit(function() {

var clientID =3D $("#clientID").val();
v= ar returnURI =3D $("#returnURI").val();
var feedScope = =3D $("#feedScope").val();

str +=3D clientID;
str +=3D "&redirect_uri=3D"= + returnURI;
str +=3D "&scope=3D" + feedScope;
str +=3D "&response_type=3Dcode";

=
var newwindow =3D window.open(str,'APIstart','height=3D400= ,width=3D400');
if (window.focus) {newwin= dow.focus()}


return false;
});
}


$(document).ready= (function() {=A0
startAPIAcess();


});
</script>






</head>
<body>


[function name=3DurlEncode]
[grep search=3D= [url]\.[/url]&replace=3D[url]%2E[/url]][grep search=3D[url]\/[/url]&= ;replace=3D[url]%2F[/url]]
[stringIn][/grep][/grep]
[/function]

<form method=3D"post" action=3D"" id=3D"grabT= oken">
<input type=3D"hidden" name=3D"_= code" id=3D"backCode" value=3D"" />
[search db=3D[dir]dbs/cells/googleDataAPI.db&eqIDdatarq=3D1]
=
[founditems]
<input type=3D"hidden" name=3D&quo= t;client_id" value=3D"[urlEncode stringIn=3D[field1]]" />=
<input type=3D"hidden" name=3D"client_secret" value= =3D"[url][field3][/url]" />
<input type=3D"h= idden" name=3D"redirect_uri" value=3D"[urlEncode string= In=3D[field2]]" />
<input type=3D"hidden" name=3D"grant_type" valu= e=3D"authorization_code" />
[/founditems]
= [/search]

</form>

<= br>


<form method=3D"post"= action=3D"" id=3D"APIstart">

[search db=3D[dir]dbs/cells= /googleDataAPI.db&eqIDdatarq=3D1]
[founditems]
<input type=3D"text" id=3D"cl= ientID" value=3D"[field1]" />
<input type=3D= "text" id=3D"returnURI" value=3D"[field2]" /&= gt;
[/founditems]
[/search]

<label&g= t;Scope: &nbsp;
<select id=3D"feedScope">
<option value=3D"https://www.google.com/calendar/feeds/"&= gt;Calendar Feeds</option>
</select>
</label>
<input type=3D&q= uot;submit" value=3D"Get Access" />
</form&g= t;




&l= t;/body>
</html>



<= br>
NEXT, THE CODE CONTAINED IN THE RETURN URI


<html>
<head>
<script src=3D"../scri= pts/jquery/jquery-1.4.4.min.js"></script>
[!]OR WHE= REVER YOUR JQUERY FILE IS[/!]


<s= cript type=3D"text/javascript">

$(document).ready(function() {=A0
var $theCod= e =3D $("#code").val();
opener.getTempToken($theCode);<= /div>
self.close();
});
</script>
<= br>
</head>
<body>

[f= ormvariables]
[showif [name]=3Dcode]

<= ;input type=3D"hidden" id=3D"code" value=3D"[value= ]" />[value]
[/showif]

[/formvariables]


</body>
</html>


LAST, THE FINAL CALL TO GET API TOKENS, WHIC= H ARE STORED IN DB FOR SESSION USE (=A0grabAPIToken.dna )




[text= ]crlf=3D[unurl]%0D%0A[/unurl][/text][!]
[/!][text]dataString=3Dco= de=3D[_code]&[!]
[/!]client_id=3D[client_id= ]&[!]
[/!]client_secret=3D[client_secret]&[!]
[/!]redire= ct_uri=3D[redirect_uri]&[!]
[/!]grant_type=3D[grant_type][/te= xt][!]
[/!][text]auth_response=3D[!]
=A0 =A0 [/!][TCPco= nnect host=3Daccou= nts.google.com&SSL=3DT&port=3D443][!]
=A0 =A0 [/!][TCPsend skipheader=3DT]POST /o/oauth2/token HTTP/1.1[crlf= ][!]
=A0 =A0 [/!]Hos= t: accounts.google= .com[crlf][!]
=A0 =A0 [/!]Content-Type: application/x-www-form-urlencoded[crlf][!]
=A0 =A0 [/!]Content-Length: [countchars][dataString][/countChars][= crlf][!]
=A0 =A0 [/!]Connection: close[crlf][!]
[/!][crlf][!]
=A0 =A0 [/!][dataString][crlf][!]
=A0 =A0 [/!][/TCPSend][!]<= /div>
=A0 =A0 [/!][/TCPconnect][/text][!]
[/!]

=


[!] A HACKY WAY OF GETTING THE JSO= N DATA INSTEAD OF USING JAVASCRIPT [/!]
[text]thestr=3D[getchars start=3D1&end=3D&trim=3Dleft][auth_re= sponse][/getchars][/text]

[text]thestr=3D[grep sea= rch=3D\{&replace=3D][grep search=3D\}&replace=3D][thestr][/grep][/g= rep][/text]

[listwords words=3D[thestr]&delimiters=3D,][!]
[/!][text][listwords words=3D[grep search=3D\"&replace=3D][w= ord][/grep]&delimiters=3D:][word][showif [index]=3D1]=3D[/showif][/list= words][/text][!]
[/!][/listwords]
[!] A HACKY WAY OF GETTING THE JSON DATA IN= STEAD OF USING JAVASCRIPT [/!]



=
[if ("[error]"!"[raw][error][/raw]")]
[then]ALERT THERE IS AN ERROR[/then]
[else]

[!]IF SUCCESSFUL YOU WILL GET - =A0ACCESS_TOKEN AND REFRESH_TOKEN = VALUES[/!]

[replace db=3D[dir]dbs/cells/gDataConne= cts.db&eqFIELD1datarq=3D[thisUser]&eqFIELD2datarq=3D[_scope]&ap= pend=3DT&autonumber=3DID][!]
[/!]field1=3D[thisUser]&field2=3D[_scope]&field3=3D[date]&= field4=3D[time]&field5=3D[access_token]&field6=3D[refresh_token][!]=
[/!][text]streamID=3D[thisautonumber][/text][/replace]
[if ("[streamID]"= =3D"") | ("[streamID]"=3D"[raw][streamID][/raw]&qu= ot;)]
[then][search db=3D[dir]d= bs/cells/gDataConnects.db&eqFIELD1datarq=3D[thisUser]&eqFIELD2datar= q=3D[_scope]&max=3D1][founditems][id][/founditems][/search][/then]
[else][streamID][/else]
<= div>[/if]

=

[/else]
[/if]



A COUPLE FINAL NOTES...

<= div>1) if you use the POST method, your parameters should be sent in the bo= dy, not in the url. =A0Otherwise that is a GET request.
2) if you= use HTTP 1.1, you need to include in the headers..

Connection: close

so the conne= ction is not persistent



<= div>
I put the hours in on this, and I don't even use it = now. =A0So hopefully others can glean something from it. =A0Hopefully it wo= rks out for you.



On = Aug 6, 2013, at 11:35 PM, David Bastedo wrote:

<= div> Hi,

I can't seem to make this work and I am hoping somebod= y can help or point me in the right direction.

I can get to st= ep 4 but have been unable to exchange the authorization code for an access = token.

I've tried a couple of variations of Tom's twitter code, = but I just get hung up - which I have read is because of HTTP/1.1 vs. 1.0 a= nd the expectation of a persistent connection.

To get the auth= orization code, I just built a link:

[text]debug=3DT[/text]
[text]client_id=3DXXXXX[/text]
[text]redir= ect_uri=3DXXXXX[/text]
[text]client_secret=3DXXXX[/text]
[text]theSco= pe=3Dhttps://www.googleapis.com/auth/youtube.readonly[/text]=

<a href=3D"https://accounts.google.com/o/oauth2/auth?client_id=3D[clie= nt_id]&redirect_uri=3D[redirect_uri]&scope=3D[theScope]&respons= e_type=3Dcode&access_type=3Doffline&state=3D2">Ask</= a>


which gets me to

[showif [sta= te]=3D2]

code: [code]<br />

--> insert fa= iled code here to get json response

[/showif]<= br>
I have tried multiple variations of:


[/!][text]co= ntent=3Dgrant_type=3Dauthorization_code[/text][!]

[/!][text]jsonResp= onse=3D[TCPConnect host=3Daccounts.google.com&port=3D443&ssl=3DT][!]
[/!][tcpsend skipheader=3DF]POST /o/oauth2/token?code=3D[code]&[!]
[= /!]client_id=3D[client_id]&[!]
[/!]client_secret=3D[client_secret]&a= mp;[!]
[/!]redirect_uri=3D[redirect_uri]&grant_type=3Dauthorization_= code HTTP/1.1[CRLF][!]
[/!]Host: account= s.google.com[CRLF][!]
[/!]Content-type: application/x-www-form-urlen= coded[CRLF][!]
[/!][/tcpsend][/tcpconnect][/text][!]

## debug inf= o ##
[/!][showif [debug]=3DT]<h3>OAuth Json Response</h3>
<pre>[jsonResponse]</pre>[/showif][!]

<= div>

Tom's version for twitter worked perfectly but t= he YT format is different.

thanks in advance!!

d.
--------------------------------------------------------- This message is sent to you because you are subscribed to the mailing list . To unsubscribe, E-mail to: archives: http://mail.webdna.us/list/talk@webdna.us Bug Reporting: suppo= rt@webdna.us

--------------------------------------------------------- This message is sent to you because you are subscribed to the mailing list . To unsubscribe, E-mail to: archives: http://mail.webdna.us/list/talk@webdna.us Bug Reporting: suppo= rt@webdna.us



--
David B= astedo

Ten Plus One Communic= ations Inc.
http://= www.10plus1.com
416.277.4499

--20cf30223ab542cd1904e35c7460-- Associated Messages, from the most recent to the oldest:

    
  1. Re: [WebDNA] YouTube API v2.0 - OAuth 2.0 Authorization (David Bastedo 2013)
  2. Re: [WebDNA] YouTube API v2.0 - OAuth 2.0 Authorization (aaronmichaelmusic@gmail.com 2013)
  3. [WebDNA] YouTube API v2.0 - OAuth 2.0 Authorization (David Bastedo 2013)
--20cf30223ab542cd1904e35c7460 Content-Type: text/plain; charset=ISO-8859-1 Thank you!!!! That's awesome. That did it. I just had to change one variable. I can't spend more time on it until later today/night, but this worked for me perfectly!! The key, that I was missing, was the content length and connection close. Though I think it is specifically the content length that did the trick. Thanks again!! d. [text]crlf=[unurl]%0D%0A[/unurl][/text][!] [/!][text]dataString=code=[_code]&[!] [/!]client_id=[client_id]&[!] [/!]client_secret=[client_secret]&[!] [/!]redirect_uri=[redirect_uri]&[!] [/!]grant_type=authorization_code[/text][!] [/!][text]auth_response=[!] [/!][TCPconnect host=accounts.google.com&SSL=T&port=443][!] [/!][TCPsend skipheader=T]POST /o/oauth2/token HTTP/1.1[crlf][!] [/!]Host: accounts.google.com[crlf][!] [/!]Content-Type: application/x-www-form-urlencoded[crlf][!] [/!]Content-Length: [countchars][dataString][/countChars][crlf][!] [/!]Connection: close[crlf][!] [/!][crlf][!] [/!][dataString][crlf][!] [/!][/TCPSend][!] [/!][/TCPconnect][/text][!] [/!] auth_response: [auth_response] On Wed, Aug 7, 2013 at 3:09 AM, wrote: > okay, I can't guarantee that this is 100% working code. I had to dig back > to some old code I wrote a couple years ago to connect to Google Calendar > feeds via Oauth2. Amidst the code I found were versions leading up to this > that didn't work great. Also, this isn't dainty but I remember whatever I > ended up did work. In any case you should be able to get something from > it... and maybe a little more. > > The Oauth2 process is a multistep process. The first step is sending some > info to a google url where the user can authorize access which will then > send back a temporary token to the redirect uri you specify. This temp > token is used to create the real deal tokens you'll be getting with the > tcpsend > > Here's how I mostly remember doing it... (I used a bit of javascript and > ajax to move the information around nicely) > > #1 --> I stored my api creds in a database. The first page populates a > form with that info that then opens a popup window (the initial google > access url). > #2 --> the redirect URI I specified also has some javascript that sends > the response w/ token back to another form on the initial page. Then, that > form is submitted via ajax to another google authorization dna script. > #3 --> The final tokens retrieved from the ajax call are stored into > another database to be used for further api requests during the session. > > I'm not going to deconstruct everything, but you should get the gist by > reviewing the code. > > so here it is... > > > THE STARTING PAGE > > > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> > > > > > Google Data API Access > > > [!]INCLUDE A JQUERY JS FILE HERE[/!] > > > > > > > > > > > > > [function name=urlEncode] > [grep search=[url]\.[/url]&replace=[url]%2E[/url]][grep > search=[url]\/[/url]&replace=[url]%2F[/url]] > [stringIn][/grep][/grep] > [/function] > >
> > [search db=[dir]dbs/cells/googleDataAPI.db&eqIDdatarq=1] > [founditems] > > [url][field3][/url]" /> > > > [/founditems] > [/search] > >
> > > > >
> > [search db=[dir]dbs/cells/googleDataAPI.db&eqIDdatarq=1] > [founditems] > > > [/founditems] > [/search] > > > >
> > > > > > > > > > > NEXT, THE CODE CONTAINED IN THE RETURN URI > > > > > > [!]OR WHEREVER YOUR JQUERY FILE IS[/!] > > > > > > > > [formvariables] > [showif [name]=code] > > [value] > [/showif] > > [/formvariables] > > > > > > > LAST, THE FINAL CALL TO GET API TOKENS, WHICH ARE STORED IN DB FOR SESSION > USE ( grabAPIToken.dna ) > > > > > [text]crlf=[unurl]%0D%0A[/unurl][/text][!] > [/!][text]dataString=code=[_code]&[!] > [/!]client_id=[client_id]&[!] > [/!]client_secret=[client_secret]&[!] > [/!]redirect_uri=[redirect_uri]&[!] > [/!]grant_type=[grant_type][/text][!] > [/!][text]auth_response=[!] > [/!][TCPconnect host=accounts.google.com&SSL=T&port=443][!] > [/!][TCPsend skipheader=T]POST /o/oauth2/token HTTP/1.1[crlf][!] > [/!]Host: accounts.google.com[crlf][!] > [/!]Content-Type: application/x-www-form-urlencoded[crlf][!] > [/!]Content-Length: [countchars][dataString][/countChars][crlf][!] > [/!]Connection: close[crlf][!] > [/!][crlf][!] > [/!][dataString][crlf][!] > [/!][/TCPSend][!] > [/!][/TCPconnect][/text][!] > [/!] > > > > [!] A HACKY WAY OF GETTING THE JSON DATA INSTEAD OF USING JAVASCRIPT [/!] > [text]thestr=[getchars > start=1&end=&trim=left][auth_response][/getchars][/text] > > [text]thestr=[grep search=\{&replace=][grep > search=\}&replace=][thestr][/grep][/grep][/text] > > [listwords words=[thestr]&delimiters=,][!] > [/!][text][listwords words=[grep > search=\"&replace=][word][/grep]&delimiters=:][word][showif > [index]=1]=[/showif][/listwords][/text][!] > [/!][/listwords] > [!] A HACKY WAY OF GETTING THE JSON DATA INSTEAD OF USING JAVASCRIPT [/!] > > > > [if ("[error]"!"[raw][error][/raw]")] > [then]ALERT THERE IS AN ERROR[/then] > [else] > > [!]IF SUCCESSFUL YOU WILL GET - ACCESS_TOKEN AND REFRESH_TOKEN VALUES[/!] > > [replace > db=[dir]dbs/cells/gDataConnects.db&eqFIELD1datarq=[thisUser]&eqFIELD2datarq=[_scope]&append=T&autonumber=ID][!] > > [/!]field1=[thisUser]&field2=[_scope]&field3=[date]&field4=[time]&field5=[access_token]&field6=[refresh_token][!] > [/!][text]streamID=[thisautonumber][/text][/replace] > [if ("[streamID]"="") | ("[streamID]"="[raw][streamID][/raw]")] > [then][search > db=[dir]dbs/cells/gDataConnects.db&eqFIELD1datarq=[thisUser]&eqFIELD2datarq=[_scope]&max=1][founditems][id][/founditems][/search][/then] > [else][streamID][/else] > [/if] > > > [/else] > [/if] > > > > A COUPLE FINAL NOTES... > > 1) if you use the POST method, your parameters should be sent in the body, > not in the url. Otherwise that is a GET request. > 2) if you use HTTP 1.1, you need to include in the headers.. > > Connection: close > > so the connection is not persistent > > > > > I put the hours in on this, and I don't even use it now. So hopefully > others can glean something from it. Hopefully it works out for you. > > > > On Aug 6, 2013, at 11:35 PM, David Bastedo wrote: > > Hi, > > I can't seem to make this work and I am hoping somebody can help or point > me in the right direction. > > I can get to step 4 but have been unable to exchange the authorization > code for an access token. > > I've tried a couple of variations of Tom's twitter code, but I just get > hung up - which I have read is because of HTTP/1.1 vs. 1.0 and the > expectation of a persistent connection. > > To get the authorization code, I just built a link: > > [text]debug=T[/text] > [text]client_id=XXXXX[/text] > [text]redirect_uri=XXXXX[/text] > [text]client_secret=XXXX[/text] > [text]theScope=https://www.googleapis.com/auth/youtube.readonly[/text] > > Ask > > > which gets me to > > [showif [state]=2] > > code: [code]
> > --> insert failed code here to get json response > > [/showif] > > I have tried multiple variations of: > > > [/!][text]content=grant_type=authorization_code[/text][!] > > [/!][text]jsonResponse=[TCPConnect host=accounts.google.com > &port=443&ssl=T][!] > [/!][tcpsend skipheader=F]POST /o/oauth2/token?code=[code]&[!] > [/!]client_id=[client_id]&[!] > [/!]client_secret=[client_secret]&[!] > [/!]redirect_uri=[redirect_uri]&grant_type=authorization_code > HTTP/1.1[CRLF][!] > [/!]Host: accounts.google.com[CRLF][!] > [/!]Content-type: application/x-www-form-urlencoded[CRLF][!] > [/!][/tcpsend][/tcpconnect][/text][!] > > ## debug info ## > [/!][showif [debug]=T]

OAuth Json Response

>
[jsonResponse]
[/showif][!] > > > > Tom's version for twitter worked perfectly but the YT format is different. > > link: > https://developers.google.com/youtube/2.0/developers_guide_protocol_oauth2#OAuth2_Server_Side_Web_Applications_Flow > > thanks in advance!! > > d. > --------------------------------------------------------- This message > is sent to you because you are subscribed to the mailing list **. To > unsubscribe, E-mail to: ** archives: > http://mail.webdna.us/list/talk@webdna.us Bug Reporting: support@webdna.us > **** > > > --------------------------------------------------------- This message is > sent to you because you are subscribed to the mailing list **. To > unsubscribe, E-mail to: ** archives: > http://mail.webdna.us/list/talk@webdna.us Bug Reporting: support@webdna.us -- David Bastedo Ten Plus One Communications Inc. http://www.10plus1.com 416.277.4499 --20cf30223ab542cd1904e35c7460 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Thank you!!!! That's awesome.

That did it. I just had to change one variable. I can't spend more = time on it until later today/night, but this worked for me perfectly!!

The key, that I was missing, was the content length and connectio= n close. Though I think it is specifically the content length that did the = trick.

Thanks again!!

d.

[text]crlf=3D[unurl]%0D%0A[/unurl][/text][!]
[/!][text]dataStri= ng=3Dcode=3D[_code]&[!]
[/!]client_id=3D[client_id]&[!]
[/!]c= lient_secret=3D[client_secret]&[!]
[/!]redirect_uri=3D[redirect_uri]= &[!]
[/!]grant_type=3Dauthorization_code[/text][!]
[/!][text]auth_response=3D= [!]
=A0=A0=A0 [/!][TCPconnect host=3Daccounts.google.com&SSL=3DT&port=3D443][!]
=A0=A0=A0 [/!= ][TCPsend skipheader=3DT]POST /o/oauth2/token HTTP/1.1[crlf][!]=A0=A0=A0 =A0=A0=A0 [/!]Host: accounts.google.= com[crlf][!]
=A0=A0=A0 [/!]Content-Type: application/x-www-form-urle= ncoded[crlf][!]
=A0=A0=A0 [/!]Content-Length: [countchars][dataString][/= countChars][crlf][!]
=A0=A0=A0 [/!]Connection: close[crlf][!]
[/!][crlf][!]
=A0=A0=A0 [/!]= [dataString][crlf][!]
=A0=A0=A0 [/!][/TCPSend][!]
=A0=A0=A0 [/!][/TCP= connect][/text][!]
[/!]

auth_response: [auth_response]
<= /div>


On Wed, Aug 7, 2013 at 3:09 AM, <aaronmichaelmusic@gmail.com> wrote:
okay, I can't guarantee that this i= s 100% working code. =A0I had to dig back to some old code I wrote a couple= years ago to connect to Google Calendar feeds via Oauth2. =A0Amidst the co= de I found were versions leading up to this that didn't work great. =A0= Also, this isn't dainty but I remember whatever I ended up did work. = =A0In any case you should be able to get something from it... and maybe a l= ittle more.

The Oauth2 process is a multistep process. =A0The first step= is sending some info to a google url where the user can authorize access w= hich will then send back a temporary token to the redirect uri you specify.= =A0This temp token is used to create the real deal tokens you'll be ge= tting with the tcpsend

Here's how I mostly remember doing it... (I used a = bit of javascript and ajax to move the information around nicely)

#1 --> I stored my api creds in a database. =A0The first= page populates a form with that info that then opens a popup window (the i= nitial google access url). =A0
#2 --> the redirect URI I specified also has some javascript that s= ends the response w/ token back to another form on the initial page. =A0The= n, that form is submitted via ajax to another google authorization dna scri= pt. =A0
#3 --> The final tokens retrieved from the ajax call are stored int= o another database to be used for further api requests during the session.<= /div>

I'm not going to deconstruct everything, but y= ou should get the gist by reviewing the code.

so here it is...


THE STARTING PAGE


<!DOCTY= PE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<html xmlns=3D"http://www.w3.org/1999/xhtml"= ; xml:lang=3D"en-us">

<head>
<meta charset=3D"utf-8&q= uot; />
<title>Google Data API Access</title>


[!]INCLUDE A JQUERY JS FILE HERE[/!]

<script type=3D"text/javascript">
=

//final ajax call to get access tokens
functi= on grabToken() {

$.ajax({
type: "POST",
cache: false,
url: "grabAPIToken.dna",
data: $("#grabToken").serializeArray(),
success: function(data) = {
//redirect to ano= ther page or do something here
alert('you did it');
}
});
}

= //redirect uri calls to this function
function getTempToken(theCo= de) {
$("#backCode").val(theCode);
grabToken();
}

//starting point
function startAPIAc= ess() {
$("#APIstart").submit(function() {

var clientID =3D $("#clientID").val();
v= ar returnURI =3D $("#returnURI").val();
var feedScope = =3D $("#feedScope").val();

str +=3D clientID;
str +=3D "&redirect_uri=3D"= + returnURI;
str +=3D "&scope=3D" + feedScope;
str +=3D "&response_type=3Dcode";

=
var newwindow =3D window.open(str,'APIstart','height=3D400= ,width=3D400');
if (window.focus) {newwin= dow.focus()}


return false;
});
}


$(document).ready= (function() {=A0
startAPIAcess();


});
</script>






</head>
<body>


[function name=3DurlEncode]
[grep search=3D= [url]\.[/url]&replace=3D[url]%2E[/url]][grep search=3D[url]\/[/url]&= ;replace=3D[url]%2F[/url]]
[stringIn][/grep][/grep]
[/function]

<form method=3D"post" action=3D"" id=3D"grabT= oken">
<input type=3D"hidden" name=3D"_= code" id=3D"backCode" value=3D"" />
[search db=3D[dir]dbs/cells/googleDataAPI.db&eqIDdatarq=3D1]
=
<input type=3D"hidden" name=3D&quo= t;client_id" value=3D"[urlEncode stringIn=3D[field1]]" />=
<input type=3D"hidden" name=3D"client_secret" value= =3D"[url][field3][/url]" />
<input type=3D"h= idden" name=3D"redirect_uri" value=3D"[urlEncode string= In=3D[field2]]" />
<input type=3D"hidden" name=3D"grant_type" valu= e=3D"authorization_code" />
[/founditems]
= [/search]

</form>

<= br>


<form method=3D"post"= action=3D"" id=3D"APIstart">

[search db=3D[dir]dbs/cells= /googleDataAPI.db&eqIDdatarq=3D1]
<input type=3D"text" id=3D"cl= ientID" value=3D"[field1]" />
<input type=3D= "text" id=3D"returnURI" value=3D"[field2]" /&= gt;
[/founditems]
[/search]

<label&g= t;Scope: &nbsp;
<select id=3D"feedScope">
<option value=3D"https://www.google.com/calendar/feeds/"&= gt;Calendar Feeds</option>
</select>
</label>
<input type=3D&q= uot;submit" value=3D"Get Access" />
</form&g= t;




&l= t;/body>
</html>



<= br>
NEXT, THE CODE CONTAINED IN THE RETURN URI


<html>
<head>
<script src=3D"../scri= pts/jquery/jquery-1.4.4.min.js"></script>
[!]OR WHE= REVER YOUR JQUERY FILE IS[/!]


<s= cript type=3D"text/javascript">

$(document).ready(function() {=A0
var $theCod= e =3D $("#code").val();
opener.getTempToken($theCode);<= /div>
self.close();
});
</script>
<= br>
</head>
<body>

[f= ormvariables]
[showif [name]=3Dcode]

<= ;input type=3D"hidden" id=3D"code" value=3D"[value= ]" />[value]
[/showif]

[/formvariables]


</body>
</html>


LAST, THE FINAL CALL TO GET API TOKENS, WHIC= H ARE STORED IN DB FOR SESSION USE (=A0grabAPIToken.dna )




[text= ]crlf=3D[unurl]%0D%0A[/unurl][/text][!]
[/!][text]dataString=3Dco= de=3D[_code]&[!]
[/!]client_id=3D[client_id= ]&[!]
[/!]client_secret=3D[client_secret]&[!]
[/!]redire= ct_uri=3D[redirect_uri]&[!]
[/!]grant_type=3D[grant_type][/te= xt][!]
[/!][text]auth_response=3D[!]
=A0 =A0 [/!][TCPco= nnect host=3Daccou= nts.google.com&SSL=3DT&port=3D443][!]
=A0 =A0 [/!][TCPsend skipheader=3DT]POST /o/oauth2/token HTTP/1.1[crlf= ][!]
=A0 =A0 [/!]Hos= t: accounts.google= .com[crlf][!]
=A0 =A0 [/!]Content-Type: application/x-www-form-urlencoded[crlf][!]
=A0 =A0 [/!]Content-Length: [countchars][dataString][/countChars][= crlf][!]
=A0 =A0 [/!]Connection: close[crlf][!]
[/!][crlf][!]
=A0 =A0 [/!][dataString][crlf][!]
=A0 =A0 [/!][/TCPSend][!]<= /div>
=A0 =A0 [/!][/TCPconnect][/text][!]
[/!]

=


[!] A HACKY WAY OF GETTING THE JSO= N DATA INSTEAD OF USING JAVASCRIPT [/!]
[text]thestr=3D[getchars start=3D1&end=3D&trim=3Dleft][auth_re= sponse][/getchars][/text]

[text]thestr=3D[grep sea= rch=3D\{&replace=3D][grep search=3D\}&replace=3D][thestr][/grep][/g= rep][/text]

[listwords words=3D[thestr]&delimiters=3D,][!]
[/!][text][listwords words=3D[grep search=3D\"&replace=3D][w= ord][/grep]&delimiters=3D:][word][showif [index]=3D1]=3D[/showif][/list= words][/text][!]
[/!][/listwords]
[!] A HACKY WAY OF GETTING THE JSON DATA IN= STEAD OF USING JAVASCRIPT [/!]



=
[if ("[error]"!"[raw][error][/raw]")]
[then]ALERT THERE IS AN ERROR[/then]
[else]

[!]IF SUCCESSFUL YOU WILL GET - =A0ACCESS_TOKEN AND REFRESH_TOKEN = VALUES[/!]

[replace db=3D[dir]dbs/cells/gDataConne= cts.db&eqFIELD1datarq=3D[thisUser]&eqFIELD2datarq=3D[_scope]&ap= pend=3DT&autonumber=3DID][!]
[/!]field1=3D[thisUser]&field2=3D[_scope]&field3=3D[date]&= field4=3D[time]&field5=3D[access_token]&field6=3D[refresh_token][!]=
[/!][text]streamID=3D[thisautonumber][/text][/replace]
[if ("[streamID]"= =3D"") | ("[streamID]"=3D"[raw][streamID][/raw]&qu= ot;)]
[then][search db=3D[dir]d= bs/cells/gDataConnects.db&eqFIELD1datarq=3D[thisUser]&eqFIELD2datar= q=3D[_scope]&max=3D1][founditems][id][/founditems][/search][/then]
[else][streamID][/else]
<= div>[/if]

=

[/else]
[/if]



A COUPLE FINAL NOTES...

<= div>1) if you use the POST method, your parameters should be sent in the bo= dy, not in the url. =A0Otherwise that is a GET request.
2) if you= use HTTP 1.1, you need to include in the headers..

Connection: close

so the conne= ction is not persistent



<= div>
I put the hours in on this, and I don't even use it = now. =A0So hopefully others can glean something from it. =A0Hopefully it wo= rks out for you.



On = Aug 6, 2013, at 11:35 PM, David Bastedo wrote:

<= div> Hi,

I can't seem to make this work and I am hoping somebod= y can help or point me in the right direction.

I can get to st= ep 4 but have been unable to exchange the authorization code for an access = token.

I've tried a couple of variations of Tom's twitter code, = but I just get hung up - which I have read is because of HTTP/1.1 vs. 1.0 a= nd the expectation of a persistent connection.

To get the auth= orization code, I just built a link:

[text]debug=3DT[/text]
[text]client_id=3DXXXXX[/text]
[text]redir= ect_uri=3DXXXXX[/text]
[text]client_secret=3DXXXX[/text]
[text]theSco= pe=3Dhttps://www.googleapis.com/auth/youtube.readonly[/text]=

<a href=3D"https://accounts.google.com/o/oauth2/auth?client_id=3D[clie= nt_id]&redirect_uri=3D[redirect_uri]&scope=3D[theScope]&respons= e_type=3Dcode&access_type=3Doffline&state=3D2">Ask</= a>


which gets me to

[showif [sta= te]=3D2]

code: [code]<br />

--> insert fa= iled code here to get json response

[/showif]<= br>
I have tried multiple variations of:


[/!][text]co= ntent=3Dgrant_type=3Dauthorization_code[/text][!]

[/!][text]jsonResp= onse=3D[TCPConnect host=3Daccounts.google.com&port=3D443&ssl=3DT][!]
[/!][tcpsend skipheader=3DF]POST /o/oauth2/token?code=3D[code]&[!]
[= /!]client_id=3D[client_id]&[!]
[/!]client_secret=3D[client_secret]&a= mp;[!]
[/!]redirect_uri=3D[redirect_uri]&grant_type=3Dauthorization_= code HTTP/1.1[CRLF][!]
[/!]Host: account= s.google.com[CRLF][!]
[/!]Content-type: application/x-www-form-urlen= coded[CRLF][!]
[/!][/tcpsend][/tcpconnect][/text][!]

## debug inf= o ##
[/!][showif [debug]=3DT]<h3>OAuth Json Response</h3>
<pre>[jsonResponse]</pre>[/showif][!]

<= div>

Tom's version for twitter worked perfectly but t= he YT format is different.

thanks in advance!!

d.
--------------------------------------------------------- This message is sent to you because you are subscribed to the mailing list . To unsubscribe, E-mail to: archives: http://mail.webdna.us/list/talk@webdna.us Bug Reporting: suppo= rt@webdna.us

--------------------------------------------------------- This message is sent to you because you are subscribed to the mailing list . To unsubscribe, E-mail to: archives: http://mail.webdna.us/list/talk@webdna.us Bug Reporting: suppo= rt@webdna.us



--
David B= astedo

Ten Plus One Communic= ations Inc.
http://= www.10plus1.com
416.277.4499

--20cf30223ab542cd1904e35c7460-- David Bastedo

DOWNLOAD WEBDNA NOW!

Top Articles:

Talk List

The WebDNA community talk-list is the best place to get some help: several hundred extremely proficient programmers with an excellent knowledge of WebDNA and an excellent spirit will deliver all the tips and tricks you can imagine...

Related Readings:

ANN: Strategic Partnership with BuyStream Announced. (2000) Spiders and Bots (2000) WebCat2b15MacPlugin - showing [math] (1997) PCS Frames (1997) Access Denied! But why? (1997) Setting up shop (1997) [OT] HTML EMAIL program wanted (1999) Sensations (1997) auto adding SKUs w/DB helper (1998) delete fails (2000) Deadlock (1999) Using Plug-In while running 1.6.1 (1997) PCS Frames (1997) how to kill webcat ? (2002) RE: WebCatalog and Webstar 3.02 (1998) Code validation (was: problem using...) (2004) Custom Error Pages - what I've done (1998) WebCat2 - [format thousands] (1997) Re:[ShowIf] and empty fields (1997) URGENT! ACGI Stopped!!!! (1997)