Firebase $onAuth 在来自 Facebook 的 $authWithOAuthRedirect 之后有错误的 authData

Firebase $onAuth has wrong authData after $authWithOAuthRedirect from Facebook

我正在尝试使用 Facebook 登录验证我的 Firebase (Angularfire) 应用程序的用户。

当我使用弹出窗口 window 进行身份验证时,一切都按预期工作,但要支持尽可能多的浏览器(iOS 上的 Chrome 不支持弹出窗口,例如)我想回退到使用重定向进行身份验证($authWithOAuthRedirect)。

我已经确认我在 Facebook 中的设置是正确的(例如,我的应用程序 ID 和密码)但是当我在 Facebook 通过重定向进行身份验证后被重定向回我的应用程序时,$onAuth 触发但我没有没有我的 Facebook authData

相反,我有匿名 authData。了解一些背景知识;如果所有用户未通过其他方式进行身份验证(例如,使用 Facebook),则所有用户都将进行匿名身份验证。

我不明白为什么会这样 - 用户现在应该通过 Facebook 进行身份验证,并且拥有 Facebook authData

我的代码的例外情况如下:

当用户点击登录按钮时触发

function logIn () {
    firebaseAuth
        .$authWithOAuthRedirect('facebook', function (error) {
            if (error) {
                console.log(error);
            }
        });
}

$onAuth(在我的 Angular 应用的 run 中)

function run ($rootScope, firebaseAuth, sessionStore) {
    $rootScope
        .$on('$routeChangeError', function (event, next, prev, error) {
            if (error === 'AUTH_REQUIRED') {
                console.log(error);
            }
        });

    $rootScope
        .$on('$routeChangeSuccess', function (event, current, prev) {
            $rootScope.title = current.$$route.title;
        });

    firebaseAuth
        .$onAuth(onAuth);

    function onAuth (authData) {
        console.log(authData);
    }
}

路由解析器以其他方式匿名验证用户

function sessionState ($q, firebaseAuth) {
    var deferred = $q.defer();

    firebaseAuth
        .$requireAuth()
        .then(deferred.resolve, guest);

    return deferred.promise;

    function guest () {
        firebaseAuth
            .$authAnonymously()
            .then(deferred.resolve, rejected);
    }

    function rejected () {
        deferred.reject('AUTH_REQUIRED');
    }
}

路由解析器 (sessionState) 检查用户是否已经通过身份验证,如果没有,则尝试匿名对其进行身份验证。

Facebook 身份验证重定向后,用户已经通过身份验证,因此不需要匿名身份验证。

但是,他们好像是?由于 $onAuthauthData 记录到控制台,并且它是匿名的。

如有任何帮助,我们将不胜感激!我确定它与我的路由解析器有关,因为弹出身份验证工作正常(路由已经解析)。

编辑: 我尝试完全删除我的路由解析器以防它导致问题,但没有任何区别。用户只是 'unauthenticated' 而不是通过 Facebook 验证(在 $authWithOAuthRedirect 之后)或匿名。

更新: 我尝试使用 Twitter 和重定向传输进行身份验证,但我遇到了完全相同的问题。我也尝试过使用端口 80,而不是我的应用程序在本地提供的端口 3000,但没有任何乐趣。

更新: 当我在我的应用程序中关闭 html5Mode 模式时 - 路线现在以 #s 开头 - $authWithOAuthRedirect 完美运行.由此我只能假设$authWithOAuthRedirect不支持AngularJS的html5Mode。任何人都可以确认这是一个问题,还是我需要更改我的代码以支持 html5ModeauthWithOAuthRedirect

EXAMPLE REPO 这是一个演示问题的示例 repo:https://github.com/jonathonoates/myapp

查看 dist 目录 - 您应该可以下载此应用程序和 运行 应用程序以重现该问题。 scripts/main.js中是应用的JS;我已经添加了一些评论,但它是不言自明的。

重现问题:单击 'Facebook Login' 按钮,您将被重定向到 Facebook 以进行身份​​验证。 FB 会将您重定向回应用程序,但问题就出在这里 - 您不会通过身份验证,并且返回的 authData 将为空 - 您会在控制台中看到这个

更新: 当我在 html5Mode 中添加 hashPrefix 例如

$locationProvider
    .html5Mode(true)
    .hashPrefix('!');

该应用程序按我预期的方式工作 - 使用 Facebook 进行身份验证并且重定向传输工作。

虽然有一些小问题:

  1. URL 附加了 #%3F,在浏览器的历史记录中是 available/visible。
  2. 这将在不支持 History.pushState (html5Mode) 的浏览器中用 #! 重写 URLs,一些不太高级的搜索引擎可能会寻找 HTML 片段因为 'hashbang'.

我会考虑在从 Facebook 重定向回来时劫持 URL,而不是使用 hashPrefix。在 URL 中有一个 __firebase_request_key 可能很重要,例如

http://localhost:3000/#%3F&__firebase_request_key=

看来这确实是您所怀疑的 Firebase 与 AngularJS 的 html5mode 之间的不兼容问题。在重定向流程结束时,Firebase 将 URL 保留为“http://.../#?", and Angular apparently doesn't like that so it did a redirect to "http://.../” 此重定向会中断 Firebase(当我们尝试对后端进行身份验证时页面会重新加载),因此它无法完成身份验证过程。

我做了一个实验性修复,确保我们将 URL 恢复为 http://.../#" at the end of the redirect flow, which Angular is happy with, thus preventing the problematic redirect. You can grab it here if you like: https://mike-shared.firebaseapp.com/firebase.js

我会确保此修复程序进入下一版本的 JS 客户端。大家可以关注我们的changelog看看什么时候发布。