私は Facebook アプリを開発しています。訪問者が Facebook を通じて承認されている場合にのみ、特定のビューへのアクセスを許可したいと考えています。これは非常に単純な作業であるはずであり、IE で試してみるまではそうだと思っていました。次のコードは、Chrome と Safari で正常に動作します。フォーム認証を使用したいので、設定しました
<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 でログインと OAuth を無限にループし続ける理由を誰かが明確にしてくれませんか?
私のアプリは MVC 3、EF Code First、および Facebook C# SDK 5.0.25 を使用しています。