c# - 如何使用 Twitter 验证用户但不用于登录目的

标签 c# twitter oauth asp.net-mvc-5 linq-to-twitter

我安装了 MVC5,一天后我认为是时候寻求帮助了,我从来都不是 OAuth 大师,其他的是,但这个不是。我已经在互联网上搜索过,但没有人专门关注身份验证过程而没有其他,或者讨论过于松散,以至于我无法理解我试图学习的特定框架的逻辑概念。

我有一个 MVC Controller ,在我看来,当用户单击按钮进行身份验证时,它是一个称为社交的简单操作。所以我的网址是 http://localhost://mywebsite/enterprise/social我知道这是学校男孩的东西,但我需要帮助,我从头开始,这用于工作 1.0 OAuth .

我不想使用 Twitter 登录,它用于我多年前制作的自定义 Twitter 框,用于发推文、转发推文,基本上与在 Twitter 上的时间相同。 这不是为了他们登录网站

我希望将用户定向到 Twitter,他们登录,重定向回相同的 MVC 页面,我捕获 token ,保存到我的个人存储中,然后完成。

之后的所有调用我自己调用数据库并创建我自己的 cookie,以供将来调用,原因是它已经创建所以我将继续使用它,没有特殊目的。

那么,这是我的 Controller ,我哪里出错了?

public async Task Social(FormCollection form)
{

    //var auth = new MvcSignInAuthorizer
    var auth = new MvcAuthorizer
    {
        CredentialStore = new InMemoryCredentialStore
        {
            ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"],
            ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"]
        }
    };

    string twitterCallbackUrl = Request.Url.ToString().Replace("Begin", "Complete");
    auth.Callback = new Uri(twitterCallbackUrl);

    await auth.BeginAuthorizationAsync();
}
public async Task<PartialViewResult> CompleteAsync()
{
    var auth = new MvcAuthorizer
    {
        CredentialStore = new InMemoryCredentialStore()
    };

    await auth.CompleteAuthorizeAsync(HttpContext.Request.Url);

    var credentials = auth.CredentialStore;
    string oauthToken = credentials.OAuthToken,
           oauthTokenSecret = credentials.OAuthTokenSecret,
           screenName = credentials.ScreenName,
           userName = Membership.GetUser().UserName;
    ulong userID = credentials.UserID;


    System.Web.Profile.ProfileBase pro = System.Web.Profile.ProfileBase.Create(userName, true);
    pro.SetPropertyValue("twoauth_token", oauthToken);
    pro.SetPropertyValue("twtokensecret", oauthTokenSecret);
    pro.Save();

    HttpContext.Response.SetOauthFromCookie("twit", oauthTokenSecret, oauthToken, userName, true);

    ViewBag.IsTwitterConnected = IsTwitterConnected;
    return PartialView("_SocialPartial");
}

这是我的 Startup.cs

    public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
            // Use a cookie to temporarily store information about a user logging in with a third party login provider
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);



            app.UseTwitterAuthentication(
                new TwitterAuthenticationOptions
                {
                    ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"],
                    ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"],
                    Provider = new LinqToTwitterAuthenticationProvider()
                });

        }
    }
}

用 MVC 5 4.6.2 框架重新安排代码来完成我需要它做的事情真是太棒了!

最佳答案

我不确定您所说的“我不想使用 Twitter 登录”是什么意思。如果你指的是旧的用户名/密码凭据登录,那已经被弃用,你无论如何都不能使用它。 System.Web.Profile...SetOAuthFromCookie... 不是 LINQ to Twitter 的一部分 - 也许您指的是登录代码?

听起来您想实现一个普通的 OAuth 工作流程。在那种情况下,我使用 OAuthController 来隔离代码并简化我的调用代码,如下所示:

public class OAuthController : AsyncController
{
    public ActionResult Index()
    {
        return View();
    }

    public async Task<ActionResult> BeginAsync()
    {
        //var auth = new MvcSignInAuthorizer
        var auth = new MvcAuthorizer
        {
            CredentialStore = new SessionStateCredentialStore
            {
                ConsumerKey = ConfigurationManager.AppSettings["consumerKey"],
                ConsumerSecret = ConfigurationManager.AppSettings["consumerSecret"]
            }
        };

        string twitterCallbackUrl = Request.Url.ToString().Replace("Begin", "Complete");
        return await auth.BeginAuthorizationAsync(new Uri(twitterCallbackUrl));
    }

    public async Task<ActionResult> CompleteAsync()
    {
        var auth = new MvcAuthorizer
        {
            CredentialStore = new SessionStateCredentialStore()
        };

        await auth.CompleteAuthorizeAsync(Request.Url);

        // This is how you access credentials after authorization.
        // The oauthToken and oauthTokenSecret do not expire.
        // You can use the userID to associate the credentials with the user.
        // You can save credentials any way you want - database, 
        //   isolated storage, etc. - it's up to you.
        // You can retrieve and load all 4 credentials on subsequent 
        //   queries to avoid the need to re-authorize.
        // When you've loaded all 4 credentials, LINQ to Twitter will let 
        //   you make queries without re-authorizing.
        //
        //var credentials = auth.CredentialStore;
        //string oauthToken = credentials.OAuthToken;
        //string oauthTokenSecret = credentials.OAuthTokenSecret;
        //string screenName = credentials.ScreenName;
        //ulong userID = credentials.UserID;
        //

        return RedirectToAction("Index", "Home");
    }
}

请注意,CredentialStore 是一个 SessionStateCredentialStore,它将您的 token 保存在 session 状态中。如果您不喜欢凭据的保存方式,请实现您自己的 ICredentialStore - 它可以像那样扩展。此外,请查看 CompleteAsync 中的注释 - 它们向您展示了如何提取所有凭据以持久保存在数据库中(或者如果您愿意,还可以将特定于用户的 token 保存在 cookie 中)。

由于凭据在授权后处于 session 状态,任何需要运行 LINQ to Twitter 的代码都可以检查这些凭据是否可用,如下所示:

        if (!new SessionStateCredentialStore().HasAllCredentials()) 
            return RedirectToAction("Index", "OAuth"); 

使用 LINQ to Twitter,如果授权方拥有所有 4 个凭据,您可以实例化一个 TwitterContext 并执行您需要的操作。 HasAllCredentials() 告诉您这 4 个凭据是否都可用。如果没有,请重新启动 OAuth 流程。此演示将用户带到一个页面以手动启动授权过程,但您可以直接重定向到 BeginAsync

实际代码中的另一个改进是修改 BeginAsync,以便它从数据库(或其他存储,例如 cookie)中查找用户的凭据,填充 SessionStateCredentialStore,并重定向回调用者。如果用户凭据不可用,则让它引导用户完成 OAuth 流程,然后保存凭据,这样您就不必再次执行此操作。

如果您想查看整个演示,请访问 MVCDemo project在 LINQ to Twitter Samples 文件夹中。

如果您收到以下错误,您应该在您的 Twitter 应用程序设置中填充您的“回调 URL”。这是有人遇到同样问题的问答:

Desktop applications only support the oauth_callback value 'oob'/oauth/request_token


Receiving Server Error



Server Error in '/' Application.
<?xml version="1.0" encoding="UTF-8"?>
<hash>
 <error>Desktop applications only support the oauth_callback value 'oob'</error>
 <request>/oauth/request_token</request>
</hash>
- Please visit the LINQ to Twitter FAQ (at the HelpLink) for help on resolving this error.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: LinqToTwitter.TwitterQueryException: <?xml version="1.0" encoding="UTF-8"?>
<hash>
 <error>Desktop applications only support the oauth_callback value 'oob'</error>
 <request>/oauth/request_token</request>
</hash>
- Please visit the LINQ to Twitter FAQ (at the HelpLink) for help on resolving this error.

Source Error:


Line 55:         protected async void AuthorizeButton_Click(object sender, EventArgs e)
Line 56:         {
Line 57:             await auth.BeginAuthorizeAsync(Request.Url);
Line 58:         }
Line 59:     }


Source File: D:\Users\Errrrrrr\Documents\visual studio 2015\ForTesting\LinqToTwitter-master\Samples\net46\CSharp\AspNetSamples\WebFormsDemo\OAuth.aspx.cs    Line: 57

Stack Trace:


[TwitterQueryException: <?xml version="1.0" encoding="UTF-8"?>
<hash>
  <error>Desktop applications only support the oauth_callback value 'oob'</error>
  <request>/oauth/request_token</request>
</hash>
 - Please visit the LINQ to Twitter FAQ (at the HelpLink) for help on resolving this error.]
   LinqToTwitter.Net.<HandleUnauthorizedAsync>d__4.MoveNext() +494
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +14139120
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   LinqToTwitter.Net.<ThrowIfErrorAsync>d__0.MoveNext() +360
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +14139120
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   LinqToTwitter.<HttpGetAsync>d__57.MoveNext() +1159
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +14139120
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   LinqToTwitter.<GetRequestTokenAsync>d__50.MoveNext() +675
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +14139120
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   LinqToTwitter.<BeginAuthorizeAsync>d__14.MoveNext() +568
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +14139120
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   System.Runtime.CompilerServices.TaskAwaiter.GetResult() +28
   WebFormsDemos.<AuthorizeButton_Click>d__2.MoveNext() in D:\Users\Edddddd\Documents\visual studio 2015\ForTesting\LinqToTwitter-master\Samples\net46\CSharp\AspNetSamples\WebFormsDemo\OAuth.aspx.cs:57
   System.Runtime.CompilerServices.<>c.<ThrowAsync>b__6_0(Object state) +56
   System.Web.Util.SynchronizationHelper.SafeWrapCallback(Action action) +110
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +14139120
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +62
   System.Web.Util.WithinCancellableCallbackTaskAwaiter.GetResult() +32
   System.Web.UI.<ProcessRequestMainAsync>d__523.MoveNext() +7762

关于c# - 如何使用 Twitter 验证用户但不用于登录目的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39135727/

相关文章:

c# - 在 C# 中使用 NumericComparer 代码,为什么我的 List.Sort() 会出现转换错误?

c# - 添加文件上传到 Orchard 模块?

.net - 使用 Excel Power Query 针对 .Net Odata Web Api 进行身份验证

Java Regex - 从字符串中提取主题标签

javascript - 使用 JavaScript 发推文

windows-phone-7 - Twitter、OAuth、Hammock、TweetSharp 和 Windows Phone 7

Java : Google AppEngine : OAuth : Google Drive API to access user's Google Drive contents created by Web Application

c# - 我可以在 Mouse.Capture() 处于事件状态时获得 MouseLeave 事件吗?

c# - 在 Asp Net Core 6 中使用 Github 进行身份验证

javascript - 推特 ,"Could not authenticate you"错误