【问题标题】:Firebase $onAuth has wrong authData after $authWithOAuthRedirect from FacebookFirebase $onAuth 在来自 Facebook 的 $authWithOAuthRedirect 之后有错误的 authData
【发布时间】:2016-04-22 03:30:37
【问题描述】:

我正在尝试使用 Facebook 登录对我的 Firebase (Angularfire) 应用的用户进行身份验证。

当我使用弹出窗口进行身份验证时,一切都按预期工作,但要支持尽可能多的浏览器(例如,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 记录到控制台,并且它是匿名的。

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

编辑:我尝试完全删除我的路由解析器,以防它导致问题,但它没有任何区别。用户只是“未经身份验证”,而不是通过 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;我已经添加了几个 cmets,但这很容易解释。

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

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

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

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

虽然有几个小问题:

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

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

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

【问题讨论】:

  • Jonathon,你能试试下载 2.4.0 吗?该版本中修复了带有哈希的 URL,我怀疑它会有所帮助。
  • 那么我们需要一个最小的复制而不是代码摘录。见creating an mcve
  • 这是一个 MCVE 供您查看 - 在此我已验证 Facebook 重定向传输不适用于 html5mode 打开。我还将使用链接更新我的 Q:github.com/jonathonoates/myapp
  • 这是一个回购。运行它的步骤是什么?我是在 dist/ 还是 app/ 中查看?在什么地方?不想让人讨厌,但您需要提供足够的数据来验证和重现问题,然后我才会投入资源来提供帮助。
  • 感谢您的耐心等待;我刚刚更新了distdirectory ,其中包含一个未缩小的完整示例,其中包含一些 cmets 以便清楚起见。您应该能够只拉下dist 目录并运行应用程序来重现问题。只需单击“Facebook 登录”按钮,您就会被重定向到 Facebook 进行身份验证。 FB 会将您重定向回应用程序,但问题就在这里。您将不会通过身份验证,返回的 authData 将是 null - 您将在控制台中看到这一点。感谢您的帮助

标签: angularjs facebook oauth firebase angularfire


【解决方案1】:

看起来这确实是 Firebase 和 AngularJS 的 html5mode 之间的不兼容,正如您所怀疑的那样。在重定向流程结束时,Firebase 将 URL 保留为“http://.../#?”,Angular 显然不喜欢这样,所以它重定向到“http://.../”这个重定向中断了 Firebase(页面重新加载,而我们'正在尝试对后端进行身份验证),因此无法完成身份验证过程。

我做了一个实验性的修复,确保我们在重定向流程结束时将 URL 恢复为 http://.../#",Angular 对此很满意,从而防止了有问题的重定向。如果你愿意,可以在这里获取它: https://mike-shared.firebaseapp.com/firebase.js

我会确保这个修复进入下一个版本的 JS 客户端。您可以关注我们的changelog,了解它何时发布。

【讨论】:

  • 感谢您的回复 - 经过大量的试验和错误才到达这里,但我很高兴我们越来越接近解决方案。需要注意的一件事;我没有使用 AngularJS 2 - 我在我的应用程序和复制中使用 1.4.4。你认为这是同一个问题之一吗?
  • 哦,对不起。那只是我感到困惑。我以为您在问题中提到了 Angular 2,但我发现我错了。 :-) 我会编辑我的答案。我使用您的复制应用程序调试了这个问题,所以它绝对是一样的。 :-)
  • 太好了,我会留意下一个版本的 Firebase。希望它不会太远!很高兴我发现了一个错误 ;-)
猜你喜欢
  • 2015-10-30
  • 2015-02-06
  • 2014-12-10
  • 2016-04-11
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多