所以问题出在您实际上使用的是负载平衡器这一事实。但让我解释一下身份验证的工作原理以及如何解决您的问题。
var appCredentials = new ConsumerCredentials("", "");
var authContext = AuthFlow.InitAuthentication(appCredentials, "");
当您调用AuthFlow.InitAuthentication 时,它会返回一个IAuthenticationContext。此上下文包含处理来自 Twitter 的回调所需的所有信息。
但除此之外,Tweetinvi 在回调中添加了一个参数authorization_id,以便它可以将回调请求映射到实际的IAuthenticationContext。
var authorizationId = Request.Params.Get("authorization_id");
var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, authorizationId);
当您使用authorization_id 作为参数调用AuthFlow.CreateCredentialsFromVerifierCode 时,它会查找本地字典并尝试获取IAuthenticationContext。
因为您使用的是负载均衡器,所以执行AuthFlow.InitAuthentication 的服务器可能与您接收回调请求的服务器不同。
因为您的回调到达不同的服务器,它实际上导致AuthenticationContext 为空。
这是我在documentation中试图解释的。
如何解决?
您需要做的是存储CreateCredentialsFromVerifierCode 在收到回调时继续工作所需的IAuthenticationContext 信息。我建议您将其存储在您的数据库中。
当您收到回拨时,您必须从您的数据库中取回这些信息。为此,我建议您在最初调用 `` 时向回调 url 添加一个参数,该参数的值将身份验证 ID 存储在数据库中(例如 my_auth_db_id=42)。
var authContext = AuthFlow.InitAuthentication(appCredentials, "http://mywebsite.com?my_auth_db_id=42");
当您的回调到达时,您将能够:
var myDBAuthId = Request.Params.Get("my_auth_db_id");
使用此值,您现在可以使用所需信息(存储在数据库中)创建新令牌。
var token = new AuthenticationToken()
{
AuthorizationKey = "<from_db>",
AuthorizationSecret = "<from_db>",
ConsumerCredentials = creds
};
现在您可以完成操作了:
var userCreds = AuthFlow.CreateCredentialsFromVerifierCode(verifierCode, token );
我知道这是一篇大文章,但我想解释一下它是如何工作的。
如果有任何不妥之处,请告诉我。