[英]Facebook Login works in localhost but not in webhost
I have a class listed below: 我有一个下面列出的课程:
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;
}
}
The above class is registered in AuthConfig.cs Like so 上面的类在AuthConfig.cs中注册,像这样
OAuthWebSecurity.RegisterClient(
new FacebookScopedClient("blablabla", "blablabla",
"read_stream,status_update,publish_actions,offline_access,user_friends"), "Facebook", facebooksocialData);
And I get to use this During authentication like so 我可以像这样在身份验证期间使用它
[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
});
}
Now this works 100% as expected in Localhost, but when I upload to a remote server, it does not work for some strange reason. 现在,它可以在Localhost中按预期方式100%工作,但是当我上传到远程服务器时,由于某种奇怪的原因,它无法工作。
AuthenticationResult result =
OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
is never successful. 永远不会成功。 Please what am I doing wrong.
请我做错了什么。 I have updated the neccessary URL's @ developers.facebook.com
我已经更新了必要的URL @ Developers.facebook.com
thanks 谢谢
well I saw the problem. 好吧,我看到了问题。
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;
}
Thanks to http://savvydev.com/authenticating-facebook-users-with-mvc-4-oauth-and-obtaining-scope-permissions/ which where all these came from anyway 多亏了http://savvydev.com/authenticating-facebook-users-with-mvc-4-oauth-and-obtaining-scope-permissions/ ,所有这些都来自
Thanks everyone for contributing. 感谢大家的贡献。
Facebook uses a url that you supply that's necessary for its Open Authentication. Facebook使用您提供的开放身份验证所必需的URL。 I suspect that you have that url set up for your localhost, in which case Facebook won't allow authentication requests from any other domain.
我怀疑您为本地主机设置了该URL,在这种情况下,Facebook将不允许来自任何其他域的身份验证请求。
If that is indeed your case, you'll need to set up another Facebook App profile (call it "AppName Production" or something), and set up the site url for that app to the domain of your web host: 如果确实如此,则需要设置另一个Facebook应用程序配置文件(称为“ AppName Production”或其他名称),然后将该应用程序的网站网址设置为您的虚拟主机的域:
You'll find this setting under your app settings tab: 您可以在“应用程序设置”标签下找到此设置:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.