1

私は 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 を使用しています。

4

2 に答える 2

1

さて、予想通り、問題は [Authorize] アノテーションによって引き起こされたことがわかりました。Facebook SDK には [CanvasAuthorize] アノテーションがあり、これを使用するように切り替えると、IE は正常に動作し、永遠にログインしません。

この前に、Cookie を使用しない認証を使用してみましたが、IE はまだ一緒にプレイしたくありませんでした。

私が理解している限り、問題は Facebook アプリが IFrame 内にあるために発生します。これはおそらくクッキーと信頼で何かを台無しにします. 誰かがこれがなぜなのか知っているなら、私はそれについて聞いていただければ幸いです.

また、この [CanvasAuthorize] を使って簡単にロールを使用および維持する方法を知っている人がいれば、教えていただければ幸いです。

于 2011-05-17T20:41:56.097 に答える
0

これは明らかなようですが、IEでCookieが無効になっていないことを確認しますか?開発者ツールでCookieを無効にするオプションがあります。

于 2011-05-17T11:02:44.393 に答える