bytespider / jsOAuth

JavaScript implimentation of the OAuth protocol. Currently supports version 1.0 (RFC5849) of the specification. Node.js & CommonJS compatible.
http://bytespider.github.com/jsOAuth/
MIT License
557 stars 109 forks source link

Having problems getting this working with twitter #19

Closed dmackinn closed 12 years ago

dmackinn commented 12 years ago

Hi, I'm trying to use this to retrieve Twitter timeline data. I have an app configured under my twitter account. Using jsOAuth I get a success message back but data.text is empty. Can you assist? Here is a snippet of what I am doing (key and secret removed obviously). The consumerKey and consumerSecret values I grabbed from the OAuth settings area on my Twitter apps's detail page. var oauthConfig = { consumerKey: "", consumerSecret: "", requestTokenUrl: "https://api.twitter.com/oauth/request_token", authorizationUrl: "https://api.twitter.com/oauth/authorize", accessTokenUrl: "https://api.twitter.com/oauth/access_token"
}; var oauth = OAuth(oauthConfig); function oauthSuccess(data) { alert('Success '+data.text); } function oauthFailure(data) { alert('Something bad happened!'); } oauth.get('jsonUrl', oauthSuccess, oauthFailure);

dmackinn commented 12 years ago

I'm using Safari 5.1 for testing

bytespider commented 12 years ago

Are you using statuses/public_timeline or statuses/user_timeline? its likely you'll need to authenticate before making requests. If you haven't already, try plumbing your credentials into jsOAuth boilerplate

dmackinn commented 12 years ago

I'm using statuses/user_timeline

I tried using the boilerplate but i get this message back from twitter Woah there!

This page requires some information that was not provided. Please return to the site that sent you to this page and try again … it was probably an honest mistake.

bytespider commented 12 years ago

I've created a working demo using twitter. jsOAuth Twitter Boilerplate Please let me know if the code works for you when you put in your key and secret

bytespider commented 12 years ago

I expect you were wanting statuses/home_timeline

dmackinn commented 12 years ago

Hey, thanks for replying. I still get this error page when using your demo Woah there! This page requires some information that was not provided. Please return to the site that sent you to this page and try again … it was probably an honest mistake.

bytespider commented 12 years ago

Try the example code in chrome - you'll need to run it with cross domain xhr privileges.

You can test in chrome using the following commandline on OSX /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-web-security --allow-file-access-from-files --allow-file-access --user-data-dir=~/chrome-test/ index.html
On Ubuntu try /opt/google/chrome/google-chrome --disable-web-security --allow-file-access-from-files --allow-file-access --user-data-dir=~/chrome-test/ index.html

I must reiterate that jsOAuth is not designed for the client web-browser, unless used in an extension or application.

Ridermansb commented 12 years ago

@bytespider sorry for my ignorance, but I'm learning about OAuth and trying to use this library without success. I created a small app to try to use this code sniped you provided in kodingen (Copy and paste from here )

More details here and here

I asked some questions related to stackoverflow. oauth-and-dropbox-api and error-origin-null-is-not-allowed-by-access-control-allow-origin-in-jsoauth

In the openAuthoriseWindow function the value of url is: "https://api.twitter.com/oauth/authorize?"

Thanks for the help!

bytespider commented 12 years ago

AJAX requests from browsers violates the cross domain origin security built into browsers. There is a policy called CORS which would let you do cross origin AJAX.

jsOAuth was designed for using in client side applications, namely appcelerator titanium, adobe air and phonegap. It can also be use in browser plugins.

Move your code into a browser plugin if you can. Or if you have the time, look into Appcelerator Titanium and create an app.

Hope this helps.

On 3 Jan 2012, at 12:23 AM, Ridermanreply@reply.github.com wrote:

@bytespider sorry for my ignorance, but I'm learning about OAuth and trying to use this library without success. I created a small app to try to use this code sniped you provided in kodingen (Copy and paste from here )

More details here and here

I asked some questions related to stackoverflow. oauth-and-dropbox-api and error-origin-null-is-not-allowed-by-access-control-allow-origin-in-jsoauth

In the openAuthoriseWindow function the value of url is: "https://api.twitter.com/oauth/authorize?"

Thanks for the help!


Reply to this email directly or view it on GitHub: https://github.com/bytespider/jsOAuth/issues/19#issuecomment-3335222

Ridermansb commented 12 years ago

Disabling some options of the browser with --disable-web-security, --allow-file-access-from-files and --allow-file-access I managed to make it work !

Now my problem is use this library with "non-PIN" mode.

$("button").click(function(){
    oauth.fetchRequestToken(openAuthoriseWindow, failureHandler);
});

openAuthoriseWindow = function(url) {
    var wnd = window.open(url, 'authorise');
    //What should I do here?
}  

failureHandler = function(data) {
    console.error(data);
}

I read this article but I'm still a little confused

Note: I know jsOAuth was designed for client side applications, but I'm just learning about twitter API and OAuth.

bytespider commented 12 years ago

Sorry, I had to assume you were trying to use it for a website as I comes up time and time again despite the documentation and read me stating otherwise.

There is only 2 ways to disable PIN based auth.

There is a hack you can attempt to use if you really must remove PIN auth, which loosely involves screen scraping the auth window popup and closing it and then setting it using setVerifier. I have achieved this previously by setting a timer at intervals to check for the div the PIN code is in then removing the timer once its found.

The article you mentioned by Libby is for use with PhoneGap and Child browser.

Hope this helps you move forward.

Rob Griffiths Twitter: @bytespider Google+: http://bytespider.eu/+ Github: https://github.com/bytespider

bytespider.euSent with Sparrow (http://www.sparrowmailapp.com/?sig)

On Tuesday, 3 January 2012 at 12:52, Riderman wrote:

Disabling some options of the browser with --disable-web-security, --allow-file-access-from-files and --allow-file-access I managed to make it work !

Now my problem is use this library with "non-PIN" mode.

$("button").click(function(){
 oauth.fetchRequestToken(openAuthoriseWindow, failureHandler);
});

openAuthoriseWindow = function(url) {
 var wnd = window.open(url, 'authorise');
 //What should I do here?
} 

failureHandler = function(data) {
 console.error(data);
}

I read this article but I'm still a little confused

Note: I know jsOAuth was designed for client side applications, but I'm just learning about twitter API and OAuth.


Reply to this email directly or view it on GitHub: https://github.com/bytespider/jsOAuth/issues/19#issuecomment-3339425

Ridermansb commented 12 years ago

I understand, some examples using callback url?

I did some tests but I'm dubious about how to call a javascript function in the callback url

See my tests

When you click Connect to twitter, the login screen opens, then the Twitter authorize APP and after he simply calls the callback URL. I would like to close this window and call a javascript function on the page that originated.

oauth = OAuth({
            consumerKey: srv.key,
            consumerSecret: srv.secret,
            requestTokenUrl: srv.request_token,
            authorizationUrl: srv.authorize,
            accessTokenUrl: srv.access_token,
            callbackUrl: "http://ridermansb.kodingen.com/twitter.html"
        });

Screenshots

I took some Screenshots will explain better:

Authorize

after...

Result

Sorry bothering you so much, I do not know where to turn. Thanks for your help!

bytespider commented 12 years ago

At this point it looks like you are on the right track.

I'd suggest having a function in your code that is launched on document ready that looks for the token in the URL and then uses postMessage to tell the other window what to do then close itself. https://developer.mozilla.org/en/DOM/window.postMessage

Rob Griffiths Twitter: @bytespider Google+: http://bytespider.eu/+ Github: https://github.com/bytespider

bytespider.euSent with Sparrow (http://www.sparrowmailapp.com/?sig)

On Tuesday, 3 January 2012 at 13:35, Riderman wrote:

I understand, some examples using callback url?

I did some tests but I'm dubious about how to call a javascript function in the callback url

See my tests

When you click Connect to twitter, the login screen opens, then the Twitter authorize APP and after he simply calls the callback URL. I would like to close this window and call a javascript function on the page that originated.

oauth = OAuth({
 consumerKey: srv.key,
 consumerSecret: srv.secret,
 requestTokenUrl: srv.request_token,
 authorizationUrl: srv.authorize,
 accessTokenUrl: srv.access_token,
 callbackUrl: "http://ridermansb.kodingen.com/twitter.html"
 });

Screenshots

I took some Screenshots will explain better:

Authorize

after...

Result

Sorry bothering you so much, I do not know where to turn. Thanks for your help!


Reply to this email directly or view it on GitHub: https://github.com/bytespider/jsOAuth/issues/19#issuecomment-3339858

Ridermansb commented 12 years ago

It worked, thanks!

Just one last question, I promise! rs

After authentication, I retrieve the token and verify code in query string

$(document).ready(function() {

    var token = $.QueryString("oauth_token");
    var verifier = $.QueryString("oauth_verifier");
    if (token && verifier) {
        window.opener.setAccessToken(token, verifier);
        window.close();
    }
}

So send as parameter to my function setAccessToken

window.setAccessToken = function(token, verifier)  {
    oauth.setVerifier(verifier);
    oauth.fetchAccessToken(getTwittData, failureHandler);
        //or
    //oauth.setAccessToken(token, verifier);
}
bytespider commented 12 years ago

You shouldn't need the token key or secret as the request token key and secret were already collected. You just need to set the PIN and request your access token.

window.setVerifier = function(verifier)  {
    oauth.setVerifier(verifier);

    // continue the flow by fetching a access token
    oauth.fetchAccessToken(getTwittData, failureHandler);
}

I'd consider it a good idea to use a cookie or local storage to flag the fact you are waiting for a verifier PIN request and clear it once you have it, just as a little hacking protection.

Ridermansb commented 12 years ago

Need to store the authentication information so that the user does not need to authenticate yourself every time you enter the page.

Any idea how I do this?

I tried to do the following:

After you authorize my APP, I put the verifier code using localStorage:

window.setAccessToken = function(token, verifier)  {
    oauth.setVerifier(verifier);
    if (localStorage != 'undefined') {
        localStorage.setItem("verifier", verifier);
    }
    oauth.fetchAccessToken(currentUser, failureHandler);
}

When the page is loaded:

var storedVerifier = localStorage.getItem("verifier");
if (storedVerifier) {
    oauth.setVerifier(storedVerifier);
}
//Verify Auth
oauth.getJSON("https://api.twitter.com/1/account/verify_credentials.json", showUser, failureHandlerConnect);

_But nothing happens!_

Problem

After the first authentication, the user would not need to authorize my app over every time the page is reloaded.

bytespider commented 12 years ago

Looking at this, its exactly what I would have done. You can examine the local storage in chrome developer tools. Make sure if saved into there.

On 5 Jan 2012, at 05:02 PM, Ridermanreply@reply.github.com wrote:

Need to store the authentication information so that the user does not need to authenticate yourself every time you enter the page.

Any idea how I do this?

I tried to do the following:

After you authorize my APP, I put the verifier code using localStorage:

window.setAccessToken = function(token, verifier)  {
   oauth.setVerifier(verifier);
   if (localStorage != 'undefined') {
       localStorage.setItem("verifier", verifier);
   }
   oauth.fetchAccessToken(currentUser, failureHandler);
}

When the page is loaded:

var storedVerifier = localStorage.getItem("verifier");
if (storedVerifier) {
   oauth.setVerifier(storedVerifier);
}
//Verify Auth
oauth.getJSON("https://api.twitter.com/1/account/verify_credentials.json", showUser, failureHandlerConnect);

_But nothing happens!_

Problem

After the first authentication, the user would not need to authorize my app over every time the page is reloaded.


Reply to this email directly or view it on GitHub: https://github.com/bytespider/jsOAuth/issues/19#issuecomment-3372530

Ridermansb commented 12 years ago

The value seems to be right! According to my tests .. loading the page the first time nothing happens. After log in, the token and verifier are saved in localStorage. On the next page load, the values ​​are retrieved normally.

I wonder if it would be necessary to save the "token" as well, something like:

window.setAccessToken = function(token, verifier)  {
    oauth.setVerifier(verifier);
    if (localStorage != 'undefined') {
        localStorage.setItem("verifier", verifier);
        localStorage.setItem("token", token);
    }
    oauth.fetchAccessToken(currentUser, failureHandler);
}

But on page load, which would use this value?

var storedVerifier = localStorage.getItem("verifier");
var token = localStorage.getItem("token");
if (storedVerifier) {
    oauth.setVerifier(storedVerifier);
        //AND TOKEN ??    oauth.setAccessToken(??) ???
}
bytespider commented 12 years ago

Sorry, yes you need to save the token and token secret then reload them with setAccessToken(token, token_secret).

On 5 Jan 2012, at 05:23 PM, Ridermanreply@reply.github.com wrote:

The value seems to be right! According to my tests .. loading the page the first time nothing happens. After log in, the token and verifier are saved in localStorage. On the next page load, the values ​​are retrieved normally.

I wonder if it would be necessary to save the "token" as well, something like:

window.setAccessToken = function(token, verifier)  {
   oauth.setVerifier(verifier);
   if (localStorage != 'undefined') {
       localStorage.setItem("verifier", verifier);
       localStorage.setItem("token", token);
   }
   oauth.fetchAccessToken(currentUser, failureHandler);
}

But on page load, which would use this value?

var storedVerifier = localStorage.getItem("verifier");
var token = localStorage.getItem("token");
if (storedVerifier) {
   oauth.setVerifier(storedVerifier);
       //AND TOKEN ??    oauth.setAccessToken(??) ???
}

Reply to this email directly or view it on GitHub: https://github.com/bytespider/jsOAuth/issues/19#issuecomment-3372889

Ridermansb commented 12 years ago

What am I doing wrong?

$(document).ready(function() {

    oauth = OAuth({
        consumerKey: srv.key,
        consumerSecret: srv.secret,
        requestTokenUrl: srv.request_token,
        authorizationUrl: srv.authorize,
        accessTokenUrl: srv.access_token,
        callbackUrl: "--My-URL-Callback"
    });

    var storedVerifier = localStorage.getItem("verifier");
    var token = localStorage.getItem("token");
    if (storedVerifier) {
        oauth.setVerifier(storedVerifier);
        oauth.setAccessToken(token, storedVerifier);
    }

    oauth.getJSON("https://api.twitter.com/1/account/verify_credentials.json", showUser, failureHandlerConnect);
}

Error

_GET https://api.twitter.com/1/account/verify_credentials.json 401 (Unauthorized)_
Invalid / expired Token

bytespider commented 12 years ago

Okay, looks like you're storing the wrong things. You need to use getAccessToken inside your fetchAccessToken callback to get the access token key and secret and store those. I'm away from a computer right now and will reply with code later if you haven't resolved your issue.

On 5 Jan 2012, at 05:41 PM, Ridermanreply@reply.github.com wrote:

What am I doing wrong?

$(document).ready(function() {

   oauth = OAuth({
       consumerKey: srv.key,
       consumerSecret: srv.secret,
       requestTokenUrl: srv.request_token,
       authorizationUrl: srv.authorize,
       accessTokenUrl: srv.access_token,
       callbackUrl: "--My-URL-Callback"
   });

   var storedVerifier = localStorage.getItem("verifier");
   var token = localStorage.getItem("token");
   if (storedVerifier) {
       oauth.setVerifier(storedVerifier);
       oauth.setAccessToken(token, storedVerifier);
   }

   oauth.getJSON("https://api.twitter.com/1/account/verify_credentials.json", showUser, failureHandlerConnect);
}

Reply to this email directly or view it on GitHub: https://github.com/bytespider/jsOAuth/issues/19#issuecomment-3373199

Ridermansb commented 12 years ago

I think I got it! (at least so far everything is working rs)
See what I did, please, correct me if something is wrong:

window.setAccessToken = function(token, verifier)  {
    oauth.fetchAccessToken(fetchAccessTokenCallback, failureHandler);
}

fetchAccessTokenCallback = function() {

    localStorage.setItem("oAccessTokenKey", oauth.getAccessTokenKey());
    localStorage.setItem("oAccessTokenSecret", oauth.getAccessTokenSecret());

    oauth.getJSON("https://api.twitter.com/1/account/verify_credentials.json", showUser, failureHandler);
}

token and verifier in setAccessToken function, I do not use at any time (do not know how they work) Before use the oauth.setVerifier(verifier) in setAccessToken function, but I do not know what it does, I removed it and everything still works normally!

When loading the page:

var oAccessTokenKey = localStorage.getItem("oAccessTokenKey");
var oAccessTokenSecret = localStorage.getItem("oAccessTokenSecret");
if (oAccessTokenKey && oAccessTokenSecret) {
    oauth.setAccessToken(oAccessTokenKey, oAccessTokenSecret);
}

oauth.getJSON("https://api.twitter.com/1/account/verify_credentials.json", showUser, failureHandlerConnect);

Thank you for your help. If not you'd be all day today, studying about it

bytespider commented 12 years ago

Congratulations. Im pleased it all worked out for you.