Facebook 登录可以在 localhost 中使用,但不能在 webhost 中使用

2024-03-10

我有一个类如下:

public class FacebookScopedClient : IAuthenticationClient
{
    private string appId;
    private string appSecret;
    private string scope;

    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  string GetHTML(string URL)
    {
        string connectionString = URL;

        try
        {
            var myRequest = (HttpWebRequest)WebRequest.Create(connectionString);
            myRequest.Credentials = CredentialCache.DefaultCredentials;
            //// Get the response
            WebResponse webResponse = myRequest.GetResponse();
            Stream respStream = webResponse.GetResponseStream();
            ////
            var 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 (string.IsNullOrEmpty(token))
        {
            return null;
        }
        string access_token = token.Substring(token.IndexOf("access_token=", StringComparison.Ordinal), token.IndexOf("&", System.StringComparison.Ordinal));
        token = access_token.Replace("access_token=", string.Empty);
        string data = GetHTML(graphApiMe + "fields=id,name,email,username,gender,link&" + access_token);

        // this dictionary must contains
        var userData = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
        userData.Add("access_token", token);
        return userData;
    }

    public FacebookScopedClient(string appId, string appSecret, string scope)
    {
        this.appId = appId;
        this.appSecret = appSecret;
        this.scope = scope;
    }

    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=" + scope;
        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["username"];
        userData.Remove("id");
        userData.Remove("username");

        var result = new AuthenticationResult(true, ProviderName, id, username, userData);
        return result;
    }
}

上面的类是在AuthConfig.cs中注册的,就像这样

OAuthWebSecurity.RegisterClient(
    new FacebookScopedClient("blablabla", "blablabla", 
        "read_stream,status_update,publish_actions,offline_access,user_friends"), "Facebook", facebooksocialData);

我可以像这样在身份验证期间使用它

[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
    AuthenticationResult result =
        OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));


    if (!result.IsSuccessful)
    {
        return RedirectToAction("ExternalLoginFailure");
    }
    if (result.ExtraData.Keys.Contains("access_token"))
    {
        Session["token"] = result.ExtraData["access_token"];


    }


    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);
    }
    // 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;
    var client = new ComputerBeacon.Facebook.Graph.User("me", Session["token"].ToString());
    var firstName = client.FirstName;
    var lastName = client.LastName;
    var userName = client.Email;
    return View("ExternalLoginConfirmation",
                new RegisterExternalLoginModel
                    {
                        UserName = result.UserName,
                        FirstName = firstName,
                        LastName = lastName,
                        ExternalLoginData = loginData
                    });
}

现在,这在本地主机中可以 100% 正常工作,但是当我上传到远程服务器时,由于某些奇怪的原因,它无法正常工作。

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

永远不会成功。请问我做错了什么。我已经更新了必要的 URL@developers.facebook.com

thanks


好吧,我看到了问题。

public AuthenticationResult VerifyAuthentication(System.Web.HttpContextBase context)
    {
        string code = context.Request.QueryString["code"];

        string rawUrl = context.Request.Url.OriginalString;
        if (rawUrl.Contains(":80/"))
            {
            rawUrl = rawUrl.Replace(":80/", "/");
            }
        if (rawUrl.Contains(":443/"))
        {
            rawUrl = rawUrl.Replace(":443/", "/");
        }
        //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["username"];
        userData.Remove("id");
        userData.Remove("username");

        var result = new AuthenticationResult(true, ProviderName, id, username, userData);
        return result;
    }

谢谢http://savvydev.com/authenticating-facebook-users-with-mvc-4-oauth-and-obtaining-scope-permissions/ http://savvydev.com/authenticating-facebook-users-with-mvc-4-oauth-and-obtaining-scope-permissions/无论如何,所有这些都是从哪里来的

感谢大家的贡献。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Facebook 登录可以在 localhost 中使用,但不能在 webhost 中使用 的相关文章

随机推荐