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.