Search code examples
angulartypescripttwitteroauthtwitter-oauth

Twitter API Request_Token in Angular


So, I'm having trouble making a Twitter Sign-In method for my angular app. The problem is I can't even get the first step done. I need to make a post request to the request_token API (I'm following this steps https://dev.twitter.com/web/sign-in/implementing) and I'm still getting the 'Bad Authentication Data' error (Just for you to know: I've been messing around with my code to make this work and the best I've gotten is the 'Could not authenticate you' error).

So before I show my code, let me make sure I'm understanding this correctly. Since I am requesting a token, I'm not passing any access_token in my code. I'm not using the token anywhere when I create my signature and I'm passing the oauth_callback string in the Authorization request.

So, This is my code to make the POST to request_token.

callTwLogin(): void{
    const url = 'https://api.twitter.com/oauth/request_token';
    const callback = encodeURIComponent('http://127.0.0.1/');

    this.Oauth_timestamp = this.createTimestamp(); // We create a timestamp in seconds.
    this.Oauth_nonce = this.randomString(32); // We create a 32-long random string.

    this.http.post(url, {headers: new HttpHeaders().set('Content-Type','application/x-www-form-urlencoded')
                    .set('Authorization','OAuth oauth_consumer_key="'+this.Oauth_consumerkey+'", oauth_nonce="'+this.Oauth_nonce+'"oauth_signature="'+encodeURIComponent(this.createSignature())+'", oauth_signature_method="HMAC-SHA1", oauth_timestamp="'
                    +this.Oauth_timestamp+'", oauth_version="1.0"')
                    })
      .subscribe(rsp => console.log("Twitter: " +rsp)); // Should it have Access Token if it is a request token?
   }

The createTimestamp() and randomString() functions are quite straightforward so I won't show them. However, the createSignature() function is really crucial so here it is:

createSignature():string{
    let rawURL: string = "POST&" + encodeURIComponent("https://api.twitter.com/oauth/request_token") + "&";
    let parameterString: string = "include_entities=true" + 
                                    "&oauth_consumer_key=" + this.Oauth_consumerkey + 
                                    "&oauth_nonce=" + this.Oauth_nonce + 
                                    "&oauth_signature_method=HMAC-SHA1"+ 
                                    "&oauth_timestamp=" + this.Oauth_timestamp + 

                                    "&oauth_version=1.0";
    let signingString = rawURL + encodeURIComponent(parameterString);
    let signingKey = encodeURIComponent(this.ConsumerSecret) + "&"; // No TokenSecret because its Request_Token.
    let signatur: string = this.CryptoJS.HmacSHA1(signingString, signingKey).toString(this.CryptoJS.enc.Base64);
    console.log("Signatur: " + signatur);
    return signatur;
   } 

As you can see, I've deleted the token in both the signature base string and in the signinkey. What am I doing wrong? I've struggled with this for weeks and I can't get it done.

Please help me. Thank you!

===================================UPDATE 1 ==============================

So I did what I Jon Susiak asked me to do. I added the comma I forgot to add before, I add oauth_callback to my parameterString and my Authorization Request and I removed the include_entities.

This is my new createSignature Method:

let callback = "http://127.0.0.1/"
    let rawURL: string = "POST&" + encodeURIComponent("https://api.twitter.com/oauth/request_token") + "&";
    let parameterString: string =   "oauth_callback=" +callback+
                                    "&oauth_consumer_key=" + this.Oauth_consumerkey + 
                                    "&oauth_nonce=" + this.Oauth_nonce + 
                                    "&oauth_signature_method=HMAC-SHA1"+ 
                                    "&oauth_timestamp=" + this.Oauth_timestamp +        
                                    "&oauth_version=1.0";
    let signingString = rawURL + encodeURIComponent(parameterString);
    let signingKey = encodeURIComponent(this.ConsumerSecret) + "&"; // No TokenSecret because its Request_Token.
    let signatur: string = this.CryptoJS.HmacSHA1(signingString, signingKey).toString(this.CryptoJS.enc.Base64);
    console.log("Signatur: " + signatur);
    return signatur;

And my new POST Code

const url = 'https://api.twitter.com/oauth/request_token';
    const callback = encodeURIComponent('http://127.0.0.1/');
    const body = {
      oauth_callback: callback
    };
    this.Oauth_timestamp = this.createTimestamp(); // We create a timestamp in seconds.
    this.Oauth_nonce = this.randomString(32); // We create a 32-long random string.
    this.http.post(url, {headers: new HttpHeaders()
                    .set('Authorization','OAuth oauth_callback="' + callback
                    + '", oauth_consumer_key="' + this.Oauth_consumerkey
                    + '", oauth_nonce="' + this.Oauth_nonce
                    + '", oauth_signature="' + encodeURIComponent(this.createSignature())
                    + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + this.Oauth_timestamp
                    + '", oauth_version="1.0"')
                    })
      .subscribe(rsp => console.log("Twitter: " +rsp)); 

It still doesn't work, if I don't send my callback as a POST parameter, it throws 'Bad Authentication Data (Error 400)'. If i do send it as a parameter, it throws 'Could not authenticate you (Error 401)'

Please help!


Solution

  • WITH UPDATE :

    you never use body. it's the second parameter, the eventual options are the third.