skip to Main Content

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!

2

Answers


  1. First include_entities is not a parameter that is used when obtaining a request token. This parameter can be used later once you have obtained your access token.

    Second you are not including the oauth_callback parameter in either the parameter string or in the Authorization header.

    Third you have missed out a comma after the oauth_nonce in the Authorization header. Note the parameter values should be percent encoded if necessary.

    Your parameter string should therefore be as follows:

    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";
    

    Your Authorization header should be:

    '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"'
    
    Login or Signup to reply.
  2. WITH UPDATE :

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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search