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