Pergunta

Estou desenvolvendo um aplicativo do Facebook e só quero permitir o acesso a determinadas visualizações se o visitante estiver autorizado pelo Facebook.Esta deveria ser uma tarefa bem simples, e pensei que fosse, até que experimentei no IE.O código a seguir funciona bem no Chrome e no Safari.Quero usar a autenticação de Formulários e, portanto, configurei

<forms loginUrl="~/Account/Login" timeout="2880" />

em web.config.Isso direcionará o visitante para o seguinte ActionResult ao entrar no meu aplicativo:

    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);
    }

Em seguida, o usuário é redirecionado para uma página do Facebook e um token de acesso é enviado de volta para meu ActionResult do OAuth:

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");
    }

O que estou tentando fazer aqui é primeiro verificar se o token que recebo do redirecionamento é válido.Se for, extraio alguns dados sobre o visitante, como FacebookID e nome.Em seguida, combino com meu banco de dados, para ver se o usuário já existe e, se não, crio um.Também atribuo uma função ao usuário em meu provedor de funções personalizado, mas tive o problema do loop infinito antes disso.Então eu configurei

FormsAuthentication.SetAuthCookie(acc.AccountID.ToString(), false);

e presumo que este seja o ponto principal para saber se um visitante está autorizado ou não.Pelo que entendi, quando o visitante está tentando chamar um ActionResult que requer [Autorizar], o sistema verificará esse cookie.

Bem, alguém poderia esclarecer por que o código acima está funcionando no Chrome/Safari, mas continua circulando pelo Login e depois pelo OAuth infinitamente no IE?

Meu aplicativo está usando MVC 3, EF Code First e Facebook C# SDK 5.0.25

Foi útil?

Solução

Ok, descobri que o problema foi desencadeado pela anotação [Autorizar], conforme esperado.O SDK do Facebook tem uma anotação [CanvasAuthorize] e, quando mudo para usá-la, o IE funciona bem e não faz login para sempre.

Antes disso, tentei usar autenticação sem cookies, mas o IE ainda não queria participar.

Pelo que descobri, o problema ocorre porque os aplicativos do Facebook estão dentro de um IFrame.Isso supostamente estraga tudo com cookies e confiança.Se alguém souber por que isso acontece, eu gostaria de ouvir sobre isso.

Além disso, se alguém souber como usar e manter funções facilmente com este [CanvasAuthorize], ficaria feliz em saber.

Outras dicas

Eu sei que isso parece óbvio, mas você tem certeza de que os cookies não estão desativados no IE?Existe uma opção para desativar cookies nas ferramentas do desenvolvedor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top