1

I am using Tweetinvi for posting images to Twitter. From our App servers its working fine to post to Twitter. But, When tried from our load balancer getting this error -

Error:The credentials are required as the URL does not contain the credentials identifier.

Stack Trace: at Tweetinvi.AuthFlow.CreateCredentialsFromVerifierCode(String verifierCode, String authorizationId, IAuthenticationContext authContext)

My code snippet is like this -

var verifierCode = Request.Params.Get("oauth_verifier");
var authorizationId = Request.Params.Get("authorization_id");
var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, authorizationId);

I see these parameters(oauth_verifier, authorization_id,..) being passed to the callback page. But still seeing the above error in the call back page.

Note: this issue is only when I try posting to Twitter on our loadbalancer (using the individual servers working fine). Should I use a different overloaded function?

Community
  • 1
  • 1
Apparao
  • 1,634
  • 1
  • 12
  • 17

1 Answers1

2

So the problem comes from the fact that you are actually using a load balancer. But let me explain how the authentication works and how you can solve your problem.

var appCredentials = new ConsumerCredentials("", "");
var authContext = AuthFlow.InitAuthentication(appCredentials, "");

When you call AuthFlow.InitAuthentication, it returns an IAuthenticationContext. This context contains all the information required to process the callback from Twitter.

But in addition to this, Tweetinvi adds a parameter authorization_id to the callback so that it can map the callback request to an actual IAuthenticationContext.

var authorizationId = Request.Params.Get("authorization_id");
var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, authorizationId);

When you call AuthFlow.CreateCredentialsFromVerifierCode with an authorization_id as a parameter it will look into the local dictionary and try to get the IAuthenticationContext.

Because you are using a load balancer, the server executing the AuthFlow.InitAuthentication can be different from the server your receiving the callback request.

Because your callback arrives at a different server, it actually result in the AuthenticationContext being null.

This is what I tried to explain in the documentation.

How to solve this?

What you need to do is to store the IAuthenticationContext information required for the CreateCredentialsFromVerifierCode to continue its work when it receives the callback. I would suggest you store this in your database.

When you receive your callback you will have to get back these information from your db. To do that I would suggest that when you initally call the `` you add to the callback url a parameter with the value storing the authentication id in your database (e.g. my_auth_db_id=42).

var authContext = AuthFlow.InitAuthentication(appCredentials, "http://mywebsite.com?my_auth_db_id=42");

When your callback arrives you will be able to do :

var myDBAuthId = Request.Params.Get("my_auth_db_id");

With this value you can now create a new token with the required information (stored in the db).

var token = new AuthenticationToken()
{
    AuthorizationKey = "<from_db>",
    AuthorizationSecret = "<from_db>",
    ConsumerCredentials = creds
};

Now you are ready to complete the operation:

var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, token );

I realize this is a big post, but I wanted to explain how it works. Please let me know if anything does not makes sense.

Linvi
  • 2,077
  • 1
  • 14
  • 28
  • Thanks Linvi, But, From the load balancer this is succeeded - AuthFlow.InitAuthentication(applicationCredentials, callBackURL); Upon callback page is loading, AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, authorizationId); is failing. Are you sure that its some thing to do with settings (time and region correctly set up.) on load balancer? – Apparao Jun 02 '16 at 15:10
  • As a result of our conversation, a new feature will be implemented added to Tweetinvi 0.9.13.0 that will give use the ability to specify the value of the `authorization_id`. So that you can decide how you want to store the id in your database (int, long, guid...) – Linvi Jun 02 '16 at 16:50
  • Thanks Linvi for your valuable time. So, if I understand correctly - in the first step, after getting the authContext by calling - AuthFlow.InitAuthentication(applicationCredentials, callBackURL), I need to store authContext object in our DB (and map to an id)? Instead, would it be sufficient if I store only the authContext.Token.AuthorizationKey, authContext.Token.AuthorizationSecret in our DB? And in the second step (in the callback)- retrieve these values from DB and create the AuthenticationToken object. And pass it to AuthFlow.CreateCredentialsFromVerifierCode() – Apparao Jun 03 '16 at 05:07
  • 1
    That is correct. The only thing that you need to store are the `AuthorizationKey` and `AuthorizationSecret`. Though make sure that when you rebuild you `AuthenticationToken` you set the `ConsumerCredentials`. – Linvi Jun 03 '16 at 08:49
  • Also please note that I have improved the `AuthenticationFlow` yesterday so that such case are easier to implement using [Custom Identifiers](https://github.com/linvi/tweetinvi/issues/243). This will be available in release 0.9.13.0. – Linvi Jun 03 '16 at 08:51
  • Tweetinvi.dll (0.9.12.2) version has different signature - AuthFlow.CreateCredentialsFromVerifierCode(string verifierCode, IAuthenticationContext context). Struggling how to supply the token created in the previous step. Should I upgrade or downgrade the dll? I got this version when I got it using nuget packageManager – Apparao Jun 06 '16 at 06:21
  • 1
    Can we use this overloaded function - AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, authKeyFromCookie, authSecretFromCookie, key, secret) – Apparao Jun 06 '16 at 06:31
  • This is a complete solution for my question. This overloaded function is working fine. May be the documentation needs to be modified. Once again Thank you very much, – Apparao Jun 06 '16 at 07:14
  • Thé toi en version already exist in 0.9.13.0. Sorry for the confusion. – Linvi Jun 06 '16 at 07:38