加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

外部登录在MVC 4 web应用中不适用于Facebook

发布时间:2020-12-14 18:54:46 所属栏目:资源 来源:网络整理
导读:我注意到,在2017年3月27日Facebook GRAPH API到期后,我的Facebook应用程序没有提供对我的Web应用程序的访问权限. 主要OAuthWebSecurity无法从Facebook图形API获取登录状态,我已经在开发人员组中完成了 bug报告.但他们没有提供解决方案.我在这个 link中提供了
我注意到,在2017年3月27日Facebook GRAPH API到期后,我的Facebook应用程序没有提供对我的Web应用程序的访问权限.
主要OAuthWebSecurity无法从Facebook图形API获取登录状态,我已经在开发人员组中完成了 bug报告.但他们没有提供解决方案.我在这个 link中提供了一个NopCommerce的解决方案.但是我没有为MVC 4提供任何完美的解决方案.

我已经经历了这个link,他们的系统在MVC 5中接近,但是我需要在MVC4中的解决方案,并提到OWIN不支持MVC4在VS 2012
那么如何解决这个问题.自从最近一周以来我一直在经历这个问题.

主要是在这段代码中发生的例外

AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback",new { ReturnUrl = returnUrl }));

它返回IsSuccessful为false,其余参数也为null.

我已经研究过,Facebook已将API字符串的返回类型更改为JSON所以如何开发我的代码来完成这些JSON.谢谢.

更新:
这个问题还没有答复.任何人在这里帮我

解决方法

根据 Previous Answer我得给你一个解决方案.在MVC4中,每个人都写下他们的AppID和SecurityCode.由于Facebook GRAPH API的改变,以前的链接被破坏.因此,每个人都需要更改RegisterFacebookClient calss.但是这个类是.Net库中的一个密封类,所以任何人都不能扩展或覆盖它.因此,我们需要使用一个包装类.让我们考虑我的Wrapper类是FacebookClientV2Dot3因此我的班级将会
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using DotNetOpenAuth.AspNet.Clients;
using Newtonsoft.Json;

public class FacebookClientV2Dot3 : OAuth2Client
{
    #region Constants and Fields

    /// <summary>
    /// The authorization endpoint.
    /// </summary>
    private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth";

    /// <summary>
    /// The token endpoint.
    /// </summary>
    private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token";

    /// <summary>
    /// The user info endpoint.
    /// </summary>
    private const string UserInfoEndpoint = "https://graph.facebook.com/me";

    /// <summary>
    /// The app id.
    /// </summary>
    private readonly string _appId;

    /// <summary>
    /// The app secret.
    /// </summary>
    private readonly string _appSecret;

    /// <summary>
    /// The requested scopes.
    /// </summary>
    private readonly string[] _requestedScopes;

    #endregion

    /// <summary>
    /// Creates a new Facebook OAuth2 client,requesting the default "email" scope.
    /// </summary>
    /// <param name="appId">The Facebook App Id</param>
    /// <param name="appSecret">The Facebook App Secret</param>
    public FacebookClient(string appId,string appSecret)
        : this(appId,appSecret,new[] { "email" }) { }

    /// <summary>
    /// Creates a new Facebook OAuth2 client.
    /// </summary>
    /// <param name="appId">The Facebook App Id</param>
    /// <param name="appSecret">The Facebook App Secret</param>
    /// <param name="requestedScopes">One or more requested scopes,passed without the base URI.</param>
    public FacebookClient(string appId,string appSecret,params string[] requestedScopes)
        : base("facebook")
    {
        if (string.IsNullOrWhiteSpace(appId))
            throw new ArgumentNullException("appId");

        if (string.IsNullOrWhiteSpace(appSecret))
            throw new ArgumentNullException("appSecret");

        if (requestedScopes == null)
            throw new ArgumentNullException("requestedScopes");

        if (requestedScopes.Length == 0)
            throw new ArgumentException("One or more scopes must be requested.","requestedScopes");

        _appId = appId;
        _appSecret = appSecret;
        _requestedScopes = requestedScopes;
    }

    protected override Uri GetServiceLoginUrl(Uri returnUrl)
    {
        var state = string.IsNullOrEmpty(returnUrl.Query) ? string.Empty : returnUrl.Query.Substring(1);

        return BuildUri(AuthorizationEndpoint,new NameValueCollection
                {
                    { "client_id",_appId },{ "scope",string.Join(" ",_requestedScopes) },{ "redirect_uri",returnUrl.GetLeftPart(UriPartial.Path) },{ "state",state },});
    }

    protected override IDictionary<string,string> GetUserData(string accessToken)
    {
        var uri = BuildUri(UserInfoEndpoint,new NameValueCollection { { "access_token",accessToken } });

        var webRequest = (HttpWebRequest)WebRequest.Create(uri);

        using (var webResponse = webRequest.GetResponse())
        using (var stream = webResponse.GetResponseStream())
        {
            if (stream == null)
                return null;

            using (var textReader = new StreamReader(stream))
            {
                var json = textReader.ReadToEnd();
                var extraData = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
                var data = extraData.ToDictionary(x => x.Key,x => x.Value.ToString());

                data.Add("picture",string.Format("https://graph.facebook.com/{0}/picture",data["id"]));

                return data;
            }
        }
    }

    protected override string QueryAccessToken(Uri returnUrl,string authorizationCode)
    {
        var uri = BuildUri(TokenEndpoint,new NameValueCollection
                {
                    { "code",authorizationCode },{ "client_id",{ "client_secret",_appSecret },});

        var webRequest = (HttpWebRequest)WebRequest.Create(uri);
        string accessToken = null;
        HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();

        // handle response from FB 
        // this will not be a url with params like the first request to get the 'code'
        Encoding rEncoding = Encoding.GetEncoding(response.CharacterSet);

        using (StreamReader sr = new StreamReader(response.GetResponseStream(),rEncoding))
        {
            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            var jsonObject = serializer.DeserializeObject(sr.ReadToEnd());
            var jConvert = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jsonObject));

            Dictionary<string,object> desirializedJsonObject = JsonConvert.DeserializeObject<Dictionary<string,object>>(jConvert.ToString());
            accessToken = desirializedJsonObject["access_token"].ToString();
        }
        return accessToken;
    }

    private static Uri BuildUri(string baseUri,NameValueCollection queryParameters)
    {
        var keyValuePairs = queryParameters.AllKeys.Select(k => HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(queryParameters[k]));
        var qs = String.Join("&",keyValuePairs);

        var builder = new UriBuilder(baseUri) { Query = qs };
        return builder.Uri;
    }

    /// <summary>
    /// Facebook works best when return data be packed into a "state" parameter.
    /// This should be called before verifying the request,so that the url is rewritten to support this.
    /// </summary>
    public static void RewriteRequest()
    {
        var ctx = HttpContext.Current;

        var stateString = HttpUtility.UrlDecode(ctx.Request.QueryString["state"]);
        if (stateString == null || !stateString.Contains("__provider__=facebook"))
            return;

        var q = HttpUtility.ParseQueryString(stateString);
        q.Add(ctx.Request.QueryString);
        q.Remove("state");

        ctx.RewritePath(ctx.Request.Path + "?" + q);
    }
}

看这里,我已经通过较新版本的链接取代了所有的API链接.

现在你需要修改你的

AuthConfig

只需使用包装类

OAuthWebSecurity.RegisterClient(new FacebookClientV2Dot3("AppID","HassedPassword"));

那么一切都成功了你的facebook登录将会回到以前的状态.

但是,您可能面临新的API,而不是以前的API,问题是IP白名单.喜欢这个image.希望你只需要这个.快乐编码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读