Ras*_*sen 6 c# asp.net-mvc facebook oauth
使用新的OAuthWebSecurity对Facebook进行身份验证,我在我的Facebook应用程序中添加了电子邮件权限.现在,正如我可以阅读的那样,我需要定义一个范围,以便能够在结果中实际获取电子邮件.到目前为止没有范围我没有收到用户的电子邮件,我不知道为什么因为我看不到在哪里定义"范围".
这只是ASP.NET MVC 4默认身份验证控制器外部登录的一小部分.
Var*_*rji 21
首先,extraData参数不会传递给facebook.它仅供内部使用.请参阅以下链接,了解如何在您的网站上使用此数据:
现在,到了肉:
除了这些方法RegisterFacebookClient
,RegisterYahooClient
在等OAuthWebSecurity
,还有一个通用的方法RegisterClient
.这是我们将用于此解决方案的方法.
这个想法来自以下网站提供的代码:http: //mvc4beginner.com/Sample-Code/Facebook-Twitter/MVC-4-oAuth-Facebook-Login-EMail-Problem-Solved.html
但是,我们不会使用解决方案提供的hacky方法.相反,我们将创建一个FacebookScopedClient
将要实现的新类IAuthenticationClient
.然后我们将使用以下命令注册该类:
OAuthWebSecurity.RegisterClient(new FacebookScopedClient("your_app_id", "your_app_secret"), "Facebook", null);
Run Code Online (Sandbox Code Playgroud)
在AuthConfig.cs中
该类的代码是:
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
public class FacebookScopedClient : IAuthenticationClient
{
private string appId;
private string appSecret;
private const string baseUrl = "https://www.facebook.com/dialog/oauth?client_id=";
public const string graphApiToken = "https://graph.facebook.com/oauth/access_token?";
public const string graphApiMe = "https://graph.facebook.com/me?";
private static string GetHTML(string URL)
{
string connectionString = URL;
try
{
System.Net.HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(connectionString);
myRequest.Credentials = CredentialCache.DefaultCredentials;
//// Get the response
WebResponse webResponse = myRequest.GetResponse();
Stream respStream = webResponse.GetResponseStream();
////
StreamReader ioStream = new StreamReader(respStream);
string pageContent = ioStream.ReadToEnd();
//// Close streams
ioStream.Close();
respStream.Close();
return pageContent;
}
catch (Exception)
{
}
return null;
}
private IDictionary<string, string> GetUserData(string accessCode, string redirectURI)
{
string token = GetHTML(graphApiToken + "client_id=" + appId + "&redirect_uri=" + HttpUtility.UrlEncode(redirectURI) + "&client_secret=" + appSecret + "&code=" + accessCode);
if (token == null || token == "")
{
return null;
}
string data = GetHTML(graphApiMe + "fields=id,name,email,gender,link&access_token=" + token.Substring("access_token=", "&"));
// this dictionary must contains
Dictionary<string, string> userData = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
return userData;
}
public FacebookScopedClient(string appId, string appSecret)
{
this.appId = appId;
this.appSecret = appSecret;
}
public string ProviderName
{
get { return "Facebook"; }
}
public void RequestAuthentication(System.Web.HttpContextBase context, Uri returnUrl)
{
string url = baseUrl + appId + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString()) + "&scope=email";
context.Response.Redirect(url);
}
public AuthenticationResult VerifyAuthentication(System.Web.HttpContextBase context)
{
string code = context.Request.QueryString["code"];
string rawUrl = context.Request.Url.OriginalString;
//From this we need to remove code portion
rawUrl = Regex.Replace(rawUrl, "&code=[^&]*", "");
IDictionary<string, string> userData = GetUserData(code, rawUrl);
if (userData == null)
return new AuthenticationResult(false, ProviderName, null, null, null);
string id = userData["id"];
string username = userData["email"];
userData.Remove("id");
userData.Remove("email");
AuthenticationResult result = new AuthenticationResult(true, ProviderName, id, username, userData);
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
现在在
public ActionResult ExternalLoginCallback(string returnUrl)
Run Code Online (Sandbox Code Playgroud)
方法中AccountController
,result.ExtraData
应该有电子邮件.
编辑:我在这篇文章中遗漏了一些代码.我在下面添加它:
public static class String
{
public static string Substring(this string str, string StartString, string EndString)
{
if (str.Contains(StartString))
{
int iStart = str.IndexOf(StartString) + StartString.Length;
int iEnd = str.IndexOf(EndString, iStart);
return str.Substring(iStart, (iEnd - iStart));
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
干杯!
Pus*_*ots 13
更新MVC4 Internet项目中的NuGet包.
DotNetOpenAuthCore.它会自动更新所有依赖项.
现在result.UserName将包含电子邮件地址而不是您的名字.
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return RedirectToAction("ExternalLoginFailure");
}
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return RedirectToLocal(returnUrl);
}
if (User.Identity.IsAuthenticated)
{
// If the current user is logged in add the new account
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
return RedirectToLocal(returnUrl);
}
else
{
// User is new, ask for their desired membership name
string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
ViewBag.ReturnUrl = returnUrl;
return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
}
}
Run Code Online (Sandbox Code Playgroud)
这是为什么?
提交修复:https: //github.com/AArnott/dotnetopenid/commit/a9d2443ee1a35f13c528cce35b5096abae7128f4
归档时间: |
|
查看次数: |
10327 次 |
最近记录: |