在 ASP.Net MVC 应用程序中从 Facebook SDK for .Net 获取 Facebook 用户访问令牌

Posted

技术标签:

【中文标题】在 ASP.Net MVC 应用程序中从 Facebook SDK for .Net 获取 Facebook 用户访问令牌【英文标题】:Getting Facebook user access token from Facebook SDK for .Net in ASP.Net MVC app 【发布时间】:2016-03-06 23:38:38 【问题描述】:

我主要使用来自 MVC 应用程序的模板来设置 Facebook 登录和注册过程。我可以使用 facebook 注册和登录,但是当我注册时,我想从 Facebook 用户那里提取额外的数据(性别、生日等),所以我不必让他们手动操作。这将在 .Net 中完成,因此我正在尝试使用 Facebook .Net SDK,但我不知道如何从 Visual studiio 为我设置的模板代码中获取用户访问令牌。这是我的代码。看看 var accessToken = ?? “var info”有一些从 facebook 返回的数据,比如提供者密钥,但没有访问令牌或用户 ID。下面的这种方法是在用户输入他们的 Facebook 凭据之后。

 [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
    
        if (User.Identity.IsAuthenticated)
        
            return RedirectToAction("Index", "Manage");
        

        if (ModelState.IsValid)
        
            // Get the information about the user from the external login provider
            var info = await AuthenticationManager.GetExternalLoginInfoAsync();
            if (info == null)
            
                return View("ExternalLoginFailure");
            
            var user = new ApplicationUser  UserName = model.UserName, Email = model.Email, MembershipCreated = DateTime.Now ; // UserName = model.UserName, Email = model.Email, MembershipCreated = DateTime.Now, Gender = model.Gender, Birthdate = birthdayDateTime ;
            var result = await UserManager.CreateAsync(user);
            if (result.Succeeded)
            
                result = await UserManager.AddLoginAsync(user.Id, info.Login);
                if (result.Succeeded)
                
                    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);

                    //try to create profile here
                    var accessToken= //need to get access token here!!!
                    FacebookClient client = new FacebookClient(accessToken);

                    dynamic fbUser = client.Get("https://www.facebook.com/" + info.DefaultUserName);

                    if (returnUrl == "/Account/Register")
                    
                        returnUrl = "/Home";
                    
                    return RedirectToLocal(returnUrl);
                
            
            AddErrors(result);
        

        ViewBag.ReturnUrl = returnUrl;
        return View(model);
    

【问题讨论】:

如何获得令牌? 【参考方案1】:

您可以将 Facebook 访问令牌添加为声明。 在 Startup.Auth.cs 文件中添加如下内容以将访问令牌保存到 ClaimsIdentity。

var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
            
                AppId = ConfigurationManager.AppSettings["Test_Facebook_AppId"],
                AppSecret = ConfigurationManager.AppSettings["Test_Facebook_AppSecret"],
                //SendAppSecretProof = true,
                Provider = new FacebookAuthenticationProvider
                
                    OnAuthenticated = (context) =>
                    
                        context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
                        return Task.FromResult(0);
                    
                
            ;

然后,您可以在需要时从声明身份中检索访问令牌。

private async Task<UserProfile> getFacebookUserProfileInfo(string userId)
        
            var claimsIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
            if (claimsIdentity != null)
            
                var facebookAccessTokenClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type.Equals("FacebookAccessToken"));
                if (facebookAccessTokenClaim != null)
                
                    var fb = new FacebookClient(facebookAccessTokenClaim.Value);
                    dynamic myInfo = fb.Get("/v2.2/me?fields=id,name,gender,about,location,link,picture.type(large)");
                    var pictureUrl = myInfo.ContainsKey("picture") ? myInfo["picture"].data["url"] : null;
                    if (!String.IsNullOrWhiteSpace(pictureUrl))
                    
                        string filename = Server.MapPath(string.Format("~/Uploads/user_profile_pictures/0.jpeg", userId));

                        await DownloadProfileImage(new Uri(pictureUrl),                     return new UserProfile
                    
                        Gender = myInfo.ContainsKey("gender") ? myInfo["gender"] : null,
                        FacebookPage = myInfo.ContainsKey("link") ? myInfo["link"] : null,
                        ProfilePicture = !string.IsNullOrEmpty(pictureUrl) ? string.Format("/Uploads/user_profile_pictures/0.jpeg", userId) : null,
                        City = myInfo.ContainsKey("location") ? myInfo["location"]["name"] : null,
                        About = myInfo.ContainsKey("about") ? myInfo["about"] : null
                    ;
                
            
            return null;
        filename);
                    

【讨论】:

以上是关于在 ASP.Net MVC 应用程序中从 Facebook SDK for .Net 获取 Facebook 用户访问令牌的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET MVC 5 中从数据库加载 Razor 视图

在 asp.net-mvc 中从服务器读取文本文件的最佳方法是啥

在 ASP.NET MVC 中从部分视图发布动态表单数据

在 asp.net core 5 MVC 视图中从 C# 代码调用 JavaScript 函数

在asp.net mvc中从具有多对多关系的数据库中获取记录

无法在 ASP.NET MVC 5 中从视图到控制器获取 Select2 标记值