【发布时间】:2023-03-12 03:45:01
【问题描述】:
我正在开发一个 Facebook 应用程序,如果访问者通过 Facebook 获得授权,我只想允许访问某些视图。这应该是一个非常简单的任务,我认为是,直到我在 IE 中尝试了它。以下代码在 Chrome 和 Safari 中运行良好。我想使用Forms认证,所以我设置了
<forms loginUrl="~/Account/Login" timeout="2880" />
在 web.config 中。这将在进入我的应用程序时将访问者引导至以下 ActionResult:
public ActionResult Login(string returnUrl)
{
ManagerGame2.Utilities.StaticDataContent.InitStaticData();
var oAuthClient = new FacebookOAuthClient();
oAuthClient.AppId = FacebookApplication.Current.AppId;
oAuthClient.RedirectUri = new Uri(redirectUrl);
var loginUri = oAuthClient.GetLoginUrl(new Dictionary<string, object> { { "state", returnUrl } });
return Redirect(loginUri.AbsoluteUri);
}
然后用户被重定向到 Facebook 页面,并且访问令牌被发送回我的 OAuth ActionResult:
public ActionResult OAuth(string code, string state)
{
FacebookOAuthResult oauthResult;
if (FacebookOAuthResult.TryParse(Request.Url, out oauthResult))
{
if (oauthResult.IsSuccess)
{
var oAuthClient = new FacebookOAuthClient();
oAuthClient.AppId = FacebookApplication.Current.AppId;
oAuthClient.AppSecret = FacebookApplication.Current.AppSecret;
oAuthClient.RedirectUri = new Uri(redirectUrl);
dynamic tokenResult = oAuthClient.ExchangeCodeForAccessToken(code);
string accessToken = tokenResult.access_token;
DateTime expiresOn = DateTime.MaxValue;
if (tokenResult.ContainsKey("expires"))
{
DateTimeConvertor.FromUnixTime(tokenResult.expires);
}
FacebookClient fbClient = new FacebookClient(accessToken);
dynamic me = fbClient.Get("me?fields=id,name");
long facebookID = Convert.ToInt64(me.id);
Account acc = (from x in db.Account.OfType<Account>() where x.FaceBookID == facebookID select x).FirstOrDefault();
if (acc == null)
{
acc = CreateAccount(me);
}
acc.LatestLogin = DateTime.Now;
db.Entry(acc).State = EntityState.Modified;
db.SaveChanges();
MemoryUserStore.CurrentAccount = acc;
UserRoleProvider usp = new UserRoleProvider();
usp.GetRolesForUser(acc.AccountID.ToString());
FormsAuthentication.SetAuthCookie(acc.AccountID.ToString(), false);
if (Url.IsLocalUrl(state))
{
return Redirect(state);
}
return RedirectToAction("Details", "Account", new { id = acc.AccountID });
}
}
return RedirectToAction("Index", "Account");
}
我在这里要做的是首先验证我从重定向返回的令牌是否有效。如果是,那么我会提取有关访问者的一些数据,例如 FacebookID 和姓名。然后我将它与我的数据库匹配,以查看用户是否已经存在,如果不存在,我创建一个。我还在我的自定义角色提供程序中为用户分配了一个角色,但在此之前我遇到了无限循环问题。然后我设置
FormsAuthentication.SetAuthCookie(acc.AccountID.ToString(), false);
我认为这是跟踪访问者是否获得授权的核心。据我了解,当访问者尝试调用需要 [Authorize] 的 ActionResult 时,系统将检查此 cookie。
那么,有人可以澄清一下为什么上面的代码在 Chrome/Safari 中运行,但在 IE 中不断循环通过 Login 和 OAuth?
我的应用使用 MVC 3、EF Code First 和 Facebook C# SDK 5.0.25
【问题讨论】:
-
Brian - web.config 中 Facebook Config 部分的设置是什么?我会从那里开始 - 我在几个应用程序上设置了您的设置,并且在所有 IE(7 及更高版本)中都可以正常工作。
标签: c# facebook oauth infinite-loop authorize