C# 添加Facebook登录按钮-can';无法在服务器端检索电子邮件地址

C# 添加Facebook登录按钮-can';无法在服务器端检索电子邮件地址,c#,asp.net,facebook,C#,Asp.net,Facebook,我正在尝试使用Facebook按钮向我的ASP.NET(C#)网站添加一个简单的登录。我只需要在服务器端检索Facebook用户登录后的电子邮件地址 我试图使用,但似乎不再使用cookie“fbs_appid”,取而代之的是一个名为“fbsr_appid”的cookie 如何更改样本以使用不同的cookie?另外,任何人都有检索登录Facebook用户电子邮件地址的工作示例 我知道有一个SDK我可以使用,但我想保持简单的事情。如果上面的示例能够工作,那么它将是完美的。这根本不是您应该做的事情,特

我正在尝试使用Facebook按钮向我的ASP.NET(C#)网站添加一个简单的登录。我只需要在服务器端检索Facebook用户登录后的电子邮件地址

我试图使用,但似乎不再使用cookie“fbs_appid”,取而代之的是一个名为“fbsr_appid”的cookie

如何更改样本以使用不同的cookie?另外,任何人都有检索登录Facebook用户电子邮件地址的工作示例


我知道有一个SDK我可以使用,但我想保持简单的事情。如果上面的示例能够工作,那么它将是完美的。

这根本不是您应该做的事情,特别是如果您试图在服务器端做这件事的话。你不应该使用cookie。 不同的SDK使事情变得更简单,它们(特别是官方SDK)与facebook的更改保持同步,而不像您提供的示例,当cookie名称更改时,它们就停止工作了

我不是一名C#开发者,也从未尝试过在那种环境下使用facebook,因此我无法确切地告诉您如何使用C#,但这是主要的概念:

当您向用户发送身份验证(假定流)时,您需要向用户请求除基本和公共用户信息之外的任何权限。 “电子邮件”字段在“扩展权限”下归档,您需要特别请求它,如下所示:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_url=YOUR_REDIRECT_URI&scope=email
(您可以阅读有关权限的更多信息)

一旦用户授权了您的应用程序并授予您权限,您就可以请求获取该数据。 您可以在服务器端通过请求图形路径(或仅通过电子邮件:)来完成此操作

您还可以在客户端通过以下方式执行此操作:


我设法用fbsr cookie获得了所需的信息。我创建了以下类,该类完成确认用户登录Facebook的所有工作,然后检索用户的详细信息:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Script.Serialization;

namespace HarlequinShared
{
public class FacebookLogin
{
    protected static string _appId = null;
    protected static string AppId
    {
        get
        {
            if (_appId == null)
                _appId = ConfigurationManager.AppSettings["FacebookAppId"] ?? null;
            return _appId;
        }
    }

    protected static string _appSecret = null;
    protected static string AppSecret
    {
        get
        {
            if (_appSecret == null)
                _appSecret = ConfigurationManager.AppSettings["FacebookAppSecret"] ?? null;
            return _appSecret;
        }
    }

    public static FacebookUser CheckLogin()
    {
        string fbsr = HttpContext.Current.Request.Cookies["fbsr_" + AppId].Value;

        int separator = fbsr.IndexOf(".");
        if (separator == -1)
        {
            return null;
        }

        string encodedSig = fbsr.Substring(0, separator);
        string payload = fbsr.Substring(separator + 1);

        string sig = Base64Decode(encodedSig);

        var serializer = new JavaScriptSerializer();
        Dictionary<string, string> data = serializer.Deserialize<Dictionary<string, string>>(Base64Decode(payload));

        if (data["algorithm"].ToUpper() != "HMAC-SHA256")
        {
            return null;
        }

        HMACSHA256 crypt = new HMACSHA256(Encoding.ASCII.GetBytes(AppSecret));
        crypt.ComputeHash(Encoding.UTF8.GetBytes(payload));
        string expectedSig = Encoding.UTF8.GetString(crypt.Hash);

        if (sig != expectedSig)
        {
            return null;
        }

        string accessTokenResponse = FileGetContents("https://graph.facebook.com/oauth/access_token?client_id=" + AppId + "&redirect_uri=&client_secret=" + AppSecret + "&code=" + data["code"]);
        NameValueCollection options = HttpUtility.ParseQueryString(accessTokenResponse);

        string userResponse = FileGetContents("https://graph.facebook.com/me?access_token=" + options["access_token"]);

        userResponse = Regex.Replace(userResponse, @"\\u([\dA-Fa-f]{4})", v => ((char)Convert.ToInt32(v.Groups[1].Value, 16)).ToString());

        FacebookUser user = new FacebookUser();

        Regex getValues = new Regex("(?<=\"email\":\")(.+?)(?=\")");
        Match infoMatch = getValues.Match(userResponse);
        user.Email = infoMatch.Value;

        getValues = new Regex("(?<=\"first_name\":\")(.+?)(?=\")");
        infoMatch = getValues.Match(userResponse);
        user.FirstName = infoMatch.Value;

        getValues = new Regex("(?<=\"last_name\":\")(.+?)(?=\")");
        infoMatch = getValues.Match(userResponse);
        user.LastName = infoMatch.Value;

        return user;
    }

    protected static string FileGetContents(string url)
    {
        string result;
        WebResponse response;
        WebRequest request = HttpWebRequest.Create(url);
        response = request.GetResponse();
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            result = sr.ReadToEnd();
            sr.Close();
        }
        return result;
    }

    protected static string Base64Decode(string input)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        string encoded = input.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
        var decoded = Convert.FromBase64String(encoded.PadRight(encoded.Length + (4 - encoded.Length % 4) % 4, '='));
        var result = encoding.GetString(decoded);
        return result;
    }

}

public class FacebookUser
{
    public string UID { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
}
这是进一步解释的


我相信这种方法是安全的,并且尽可能简单。如果有任何问题,请发表评论。

我希望用户能够在弹出窗口中登录,而不是通过重定向。因此请使用。身份验证后获取用户数据(和电子邮件字段)的过程应该是相同的。不过有一点是,为服务器端身份验证生成的令牌“生存”时间更长(我认为有效期为一个月),这与客户端生成的令牌不同。我尝试使用C#SDK,但文档不完整,中的示例不起作用(FacebookClient未被识别)。有人有SDK的工作代码吗?
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Script.Serialization;

namespace HarlequinShared
{
public class FacebookLogin
{
    protected static string _appId = null;
    protected static string AppId
    {
        get
        {
            if (_appId == null)
                _appId = ConfigurationManager.AppSettings["FacebookAppId"] ?? null;
            return _appId;
        }
    }

    protected static string _appSecret = null;
    protected static string AppSecret
    {
        get
        {
            if (_appSecret == null)
                _appSecret = ConfigurationManager.AppSettings["FacebookAppSecret"] ?? null;
            return _appSecret;
        }
    }

    public static FacebookUser CheckLogin()
    {
        string fbsr = HttpContext.Current.Request.Cookies["fbsr_" + AppId].Value;

        int separator = fbsr.IndexOf(".");
        if (separator == -1)
        {
            return null;
        }

        string encodedSig = fbsr.Substring(0, separator);
        string payload = fbsr.Substring(separator + 1);

        string sig = Base64Decode(encodedSig);

        var serializer = new JavaScriptSerializer();
        Dictionary<string, string> data = serializer.Deserialize<Dictionary<string, string>>(Base64Decode(payload));

        if (data["algorithm"].ToUpper() != "HMAC-SHA256")
        {
            return null;
        }

        HMACSHA256 crypt = new HMACSHA256(Encoding.ASCII.GetBytes(AppSecret));
        crypt.ComputeHash(Encoding.UTF8.GetBytes(payload));
        string expectedSig = Encoding.UTF8.GetString(crypt.Hash);

        if (sig != expectedSig)
        {
            return null;
        }

        string accessTokenResponse = FileGetContents("https://graph.facebook.com/oauth/access_token?client_id=" + AppId + "&redirect_uri=&client_secret=" + AppSecret + "&code=" + data["code"]);
        NameValueCollection options = HttpUtility.ParseQueryString(accessTokenResponse);

        string userResponse = FileGetContents("https://graph.facebook.com/me?access_token=" + options["access_token"]);

        userResponse = Regex.Replace(userResponse, @"\\u([\dA-Fa-f]{4})", v => ((char)Convert.ToInt32(v.Groups[1].Value, 16)).ToString());

        FacebookUser user = new FacebookUser();

        Regex getValues = new Regex("(?<=\"email\":\")(.+?)(?=\")");
        Match infoMatch = getValues.Match(userResponse);
        user.Email = infoMatch.Value;

        getValues = new Regex("(?<=\"first_name\":\")(.+?)(?=\")");
        infoMatch = getValues.Match(userResponse);
        user.FirstName = infoMatch.Value;

        getValues = new Regex("(?<=\"last_name\":\")(.+?)(?=\")");
        infoMatch = getValues.Match(userResponse);
        user.LastName = infoMatch.Value;

        return user;
    }

    protected static string FileGetContents(string url)
    {
        string result;
        WebResponse response;
        WebRequest request = HttpWebRequest.Create(url);
        response = request.GetResponse();
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            result = sr.ReadToEnd();
            sr.Close();
        }
        return result;
    }

    protected static string Base64Decode(string input)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        string encoded = input.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
        var decoded = Convert.FromBase64String(encoded.PadRight(encoded.Length + (4 - encoded.Length % 4) % 4, '='));
        var result = encoding.GetString(decoded);
        return result;
    }

}

public class FacebookUser
{
    public string UID { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
}
FacebookUser user = FacebookLogin.CheckLogin();
if (user != null)
{
Response.Write("&lt;p&gt;" + user.Email);
Response.Write("&lt;p&gt;" + user.FirstName);
Response.Write("&lt;p&gt;" + user.LastName);
}