asp.net-mvc – 具有已定义范围的.NET ASP.NET MVC应用程序Faceb
使用定义范围的Facebook
OAuth创建
.NET
ASP.NET MVC应用程序的最简单方法是什么?
我尝试了很多例子. OAuthWebSecurity.RegisterClient 不支持添加更多Facebook范围. Facebook application template创建一个画布,我需要非画布应用程序. FacebookScopedClient未满,无法使用此修复程序. 你有什么建议? 我也开放JavaScript / jQuery解决方案. 解决方法
可能我已经太迟了,但是几天前我遇到了这个问题,我发现网上只有一些不好的解决方案.所以我写了自己的解决方案,我现在才发布.
我利用DotNetOpenAuth.AspNet.Clients.OAuth2Client类来完成大部分工作.我只扩展了它以包括范围和额外的用户数据. public class FacebookExtendedClient : DotNetOpenAuth.AspNet.Clients.OAuth2Client { protected FacebookClient facebookClient; protected string fields; protected string scope; protected Func<string,object,string> fieldTransformer; protected bool emailAsUsername; protected IDictionary<string,string> userData; private string[] splittedFields; private string[] splittedScope; protected const string serviceLoginBaseUrl = "https://www.facebook.com/dialog/oauth"; protected const string serviceMeBaseUrl = "https://graph.facebook.com/me"; protected const string serviceAccessTokenBaseUrl = "https://graph.facebook.com/oauth/access_token"; /// <summary> /// Create an instrance of the class. /// </summary> /// <param name="appId">The App ID of the application used to connect to Facebook service.</param> /// <param name="appSecret">The App Secret of the application used to connect to Facebook service.</param> /// <param name="fields"> /// String containing comma separated fields to add to the request. /// If empty the request will retrieve the default fields based of the specified scope. /// </param> /// <param name="fieldTransformer"> /// Function to be applied to the values retrived from facebook. /// If null provided the method will try to cast values from object to string explicitly,/// an InvalidCastException will be thrown if the cast will not be possible. /// </param> /// <param name="scope"> /// String containing comma separated permissions to add to the request. /// If empty the request will have the basic scope. /// </param> /// <param name="emailAsUsername">Makes the email of the facebook user used as authentication username.</param> public FacebookExtendedClient(string appId,string appSecret,string fields = "",Func<string,string> fieldTransformer = null,string scope = "",bool emailAsUsername = false) : base("facebook") { if (string.IsNullOrEmpty(appId)) throw new ArgumentException("The appId argument can not be null or empty.","appId"); if (string.IsNullOrEmpty(appSecret)) throw new ArgumentException("The appSecret argument can not be null or empty.","appSecret"); fields = fields.Replace(" ",""); scope = scope.Replace(" ",""); this.splittedFields = fields.Split(','); this.splittedScope = scope.Split(','); if (emailAsUsername == true && !this.splittedFields.Contains("email") && !this.splittedScope.Contains("email")) throw new ArgumentException("The scope argument must contain the 'email' permission and the 'email' field to allow emailAsUsername to true.","scope"); this.facebookClient = new FacebookClient(); this.facebookClient.AppId = appId; this.facebookClient.AppSecret = appSecret; this.fields = fields; this.fieldTransformer = fieldTransformer; this.scope = scope; this.emailAsUsername = emailAsUsername; } public FacebookClient FacebookClient { get { return this.facebookClient; } } public IDictionary<string,string> UserData { get { return this.userData; } } protected override Uri GetServiceLoginUrl(Uri returnUrl) { Dictionary<string,object> parameters = new Dictionary<string,object>(); parameters.Add("redirect_uri",returnUrl.AbsoluteUri); if (!string.IsNullOrEmpty(this.scope)) parameters.Add("scope",this.scope); return this.facebookClient.GetLoginUrl(parameters); } protected override IDictionary<string,string> GetUserData(string accessToken) { // This method makes the AuthenticationResult's UserName property be the facebook username of the logged user,// but if the facebook username is missing the facebook id will be used. // If emailAsUsername is true then AuthenticationResult's UserName property is the email retrieved from facebook // and the facebook username can be retrieved by the key "fb_username" in this.userData FacebookClient facebookClient = new FacebookClient(accessToken); var getResult = facebookClient.Get<IDictionary<string,object>>("me",new { fields = this.fields }); Dictionary<string,string> result = new Dictionary<string,string>(); if (this.fieldTransformer != null) { foreach (var pair in getResult) result.Add(pair.Key,this.fieldTransformer(pair.Key,pair.Value)); } else { foreach (var pair in getResult) { string value = pair.Value.ToString(); if (value == null) throw new InvalidCastException("Cast not possible for the object associate to the key '" + pair.Key + "'."); result.Add(pair.Key,value); } } if (this.splittedFields.Contains("username")) result["fb_username"] = result["username"]; if (this.emailAsUsername) result["username"] = result["email"]; this.userData = result; return result; } protected override string QueryAccessToken(Uri returnUrl,string authorizationCode) { UriBuilder builder = new UriBuilder(serviceAccessTokenBaseUrl); builder.Query = string.Format("client_id={0}&client_secret={1}&redirect_uri={2}&code={3}",this.facebookClient.AppId,this.facebookClient.AppSecret,HttpUtility.UrlEncode(Encoding.ASCII.GetBytes(returnUrl.AbsoluteUri)),authorizationCode); using (WebClient client = new WebClient()) { string str = client.DownloadString(builder.Uri); if (string.IsNullOrEmpty(str)) return null; return HttpUtility.ParseQueryString(str)["access_token"]; } } } 你可以使用它在OAuthWebSecurity中注册它(在Application_Start中放置RegisterAuth方法,就像在InternetApplication模板中一样): public static class AuthConfig { public static void RegisterAuth() { configuration.LoadFromAppSettings(); OAuthWebSecurity.RegisterClient(new FacebookExtendedClient( "##YOUR_APP_ID##","##YOUR_APP_SECRET##","id,first_name,last_name,link,username,gender,email,age_range,picture.height(200)",new Func<string,string>(fieldsTransformer),"email")); } private static string fieldsTransformer(string key,object value) { switch (key) { case "picture": var data = (value as IDictionary<string,object>)["data"] as IDictionary<string,object>; return data["url"].ToString(); case "age_range": var min = (value as IDictionary<string,object>)["min"]; return min.ToString(); default: return value.ToString(); } } } 正如你在上面的例子中看到的那样,方法fieldsTransformer将获得键和值foreach字段被选中,在这种情况下,它将把facebook重新获得的对象转换为图片的url.这是一种方便的方法,如果为Func参数提供null,则将保存values对象的JSON表示. 稍后在登录后检索客户端信息,可以这样做: [Authorize] public class HomeController : Controller { public ActionResult Index() { IDictionary<string,string> userData = (OAuthWebSecurity.GetOAuthClientData("facebook").AuthenticationClient as FacebookExtendedClient).UserData; string email = userData["email"]; // If leave null the fieldTransform of the client you can access to complex properties like this: JObject picture = JObject.Parse(userData["picture"]); string url = (picture["data"] as JObject)["url"].ToString(); ViewBag.Email = userData["email"]; ViewBag.PictureUrl = url; return View(); } } 希望你喜欢这段代码,即使它有点晚了! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-core – TagHelper,用于将路由值作为链接的一部分传
- asp.net-mvc – 无法使用IIS Express在Windows 10上运行Web
- asp.net – 在ViewState或Session State中存储DataSet
- ef-code-first – 如何通过使用Identity ASP.NET MVC的代码
- .net – 什么是类的默认访问修饰符?
- 如何为ASP.NET 5 MVC 6实现NoSQL身份提供程序
- asp.net中的泛型处理程序是什么?
- .net – 为所有操作调用ActionFilterAttribute
- asp.net – 如何设置Thread.CurrentPrincipal以在整个应用程
- asp.net-mvc – Redirect和RedirectToAction之间的混淆