AngularFire2登录注销订阅身份验证问题-Angular2 [英] AngularFire2 Login Logout Subscribe to Auth issue - Angular2

查看:103
本文介绍了AngularFire2登录注销订阅身份验证问题-Angular2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好,所以我已经半天不停地尝试解决这个问题了,原因是我目前还没有起步,这是由于我对AngularFire2Angular2的了解水平

Ok so I've been banging my head against the wall for half a day trying to resolve this, reason I haven't as of yet is due to my level of knowledge with AngularFire2 and Angular2 is somewhat beginner.

我有一个应用程序,一个使用AngularFire2的简单登录表单连接到Facebook,检索用户Access TokenFacebook Id,然后调用Facebook Graph API,该返回的名字,姓氏,性别,电子邮件等

I have an application, a simple login form which uses AngularFire2 connects to Facebook, retrieves the users Access Token and Facebook Id and then calls the Facebook Graph API which returns firstname, lastname, gender, email etc.

如下所示:

loginWithFacebook(): FirebaseListObservable<string> {

    return FirebaseListObservable.create(obs => {
        this.af.auth.login({
            provider: AuthProviders.Facebook,
            method: AuthMethods.Popup,
            scope: ['public_profile']
        }).then((authState: any) => {

            let authSubscription = this.af.auth.subscribe(auth => {

             if (auth == null) return;

                let url = `https://graph.facebook.com/v2.8/${auth.facebook.uid}?fields=first_name,last_name,gender,email&access_token=${authState.facebook.accessToken}`;

                this.http.get(url).subscribe(response => {
                    let user = response.json()

                    this.af.database.object('/users/' + authState.uid).update({
                        first_name: user.first_name,
                        last_name: user.last_name,
                        display_name: auth.facebook.displayName,
                        gender: user.gender,
                        email_address: auth.facebook.email,
                        accessToken: authState.facebook.accessToken,
                        facebook_Id: auth.facebook.uid,
                    })
                },
                    err => {
                        obs.next(false);
                    });

            });

            authSubscription.unsubscribe();

            obs.next(true);

        }).catch(err => {
            obs.next(false);
        });
    });

}

Facebook Id =来自auth Access Token =来自authState

Facebook Id = Comes from auth Access Token = Comes from authState

然后我将从Facebook Graph API返回的信息保存到Firebase.

I then save the information returned from the Facebook Graph API to Firebase.

现在出现问题了,正如您在上面指定的函数中看到的那样,我已经预订了auth方法,这使我可以访问调用Facebook Id和Access Token >

Now here comes the issue, as you can see inside the function specified above, I have subscribed to the auth method, this allows me to access the Facebook Id and the Access Token which is required to call Facebook Graph API

在我的应用程序导航中,我有一个注销按钮.当用户单击此按钮时,我会呼叫

In the navigation of my application I have a logout button. When the user clicks this button I call

this.af.auth.logout();

一旦我按下登出按钮,由于订阅了auth的更改,上面指定的函数将被调用,我在其中放置了一个if语句来检查auth是否为null,如果返回则可以正常工作-对我来说似乎有点hacky.

Once I've pressed logout, my function specified above will be called due to being subscribed to the change of auth, I've placed an if statement inside to check if auth is null, if so return which is working - Seems a bit hacky to me.

如果我随后尝试重新登录,则在${auth.facebook.uid}上调用Facebook Graph API的URL失败,它指出它是undefined,我不确定这为什么会失败,因为在我看来,它被归类为新登录,因此该方法应从头到尾再次运行.

If I then try and sign back in, the url for calling Facebook Graph API fails on ${auth.facebook.uid} which states it's undefined, which I'm not entirely sure why this would fail because to me it's classed as a new login so the method should run from start to finish again.

现在我的问题是这个

如何通过facebook方法在我的Login中订阅auth?并仍然访问Facebook IdAccess Token

How can I get around subscribing to the auth within my Login with facebook method? and still access the Facebook Id and Access Token

我正在尝试找到一种方法,该方法可用于以下两种情况:

I'm trying to figure out a way whereby the method will work for two scenarios which are:

  1. 用户已存在于数据库中
  2. 该用户不存在,因此需要重新注册.

注销和注册/登录应该彼此隔离,并且不干扰彼此的职责.

The logout and Sign Up/Login should both be isolated from one another and not interfere with one another responsibilities.

如果任何人都可以分享任何知识或提出更简洁的方法,我将不胜感激.

If anyone can share any knowledge or suggest a much cleaner way of doing this I would highly appreciate it.

更新

我已经在Github上创建了一个存储库,这是我的应用程序的简化版本,它显示了我遇到的错误.

I've created a repository on Github which is a cut down version of my application and it shows the error I'm experiencing.

回购

要复制:

login.service loginWithFacebook方法内部,您将看到以下代码行:

Inside the login.service loginWithFacebook method you will see this line of code:

if (auth.facebook.uid == null) return;

对此进行评论,并按照以下步骤操作.

comment this out and follow the steps below.

  1. 在注册页面上使用Facebook登录
  2. 使用注销按钮注销
  3. 注销后立即使用Facebook重新登录

您会注意到第一次登录会起作用,一旦您注销并重新登录Facebook,图形API将由于未定义auth.facebook.uid而失败.

You will notice first time logging in it works, as soon as you signout and sign back in with facebook the graph API will fail due to auth.facebook.uid being undefined.

现在,理想情况下,我不想订阅auth事件,原因是因为我们将使用Google以及电子邮件和密码来实现登录.

Now Ideally I do not want to subscribe to the auth event reason being is because we will be implementing signin with Google and email and password.

我要订阅auth事件的唯一位置是在导航栏内,该导航栏会在用户被授权后更改菜单导航.

The only place I would like to subscribe to the auth event would be inside the nav bar which changes the menu navigation when the user becomes authorised.

注意:这已链接到Firebase上的测试帐户.解决此问题后,将删除测试帐户.因此,所有用于测试的帐户信息都将被删除.

NOTE: this is linked to a test account on firebase. Once this issue has been resolved the test account will be deleted. So all account information that has been used to test this will be deleted.

最终更新

好,所以我决定为此悬赏,以帮助找到解决方案.

Ok so I’ve decided to open a bounty on this to help find a solution.

我看到此工作的唯一方法是拥有一个登录页面,该登录页面将满足新用户和现有用户的需要,如果该用户是新用户,则使用Facebook登录,然后调用Facebook Graph API检索有关他们的信息,并然后将其保存(如果存在),则不要调用Facebook Graph API.

The only way I can see this working is having one login page, this login page will cater for new and existing user, if the user logs in with Facebook if they’re new then call Facebook Graph API retrieve information about them and then save it, if they’re existing then don’t call the Facebook Graph API.

我希望它如何工作:

新用户:

1.  User navigates to website
2.  Signs in with Facebook
3.  Popup appears
4.  Users grants the permissions I’ve requested
5.  Callback to website <- at this point I have access to users Facebook Id and accessToken via the auth
6.  Call Facebook Graph API retrieve first_name, last name etc passing in users Facebook Id and accessToken
7.  Then save the information returned from Facebook Graph to Firebase

现有用户

如果用户已经使用Facebook进行了注册,那么当他/她登录时,我不想调用Facebook Graph API,则新帐户只需要调用一次Graph.

If the user has already signed up using Facebook then when he / she signs in I don’t want to call the Facebook Graph API, the call to the Graph is only required once for new accounts.

此仓库仍然可用.

首次注册后,注销并登录后,打印到控制台的错误:

Error printed to console, after registering for the first time, logging out, logging in:

AngularFire2程序包json

AngularFire2 package json

{
  "_args": [
    [
      {
        "raw": "angularfire2@^2.0.0-beta.7",
        "scope": null,
        "escapedName": "angularfire2",
        "name": "angularfire2",
        "rawSpec": "^2.0.0-beta.7",
        "spec": ">=2.0.0-beta.7 <3.0.0",
        "type": "range"
      },
      "/Users/Scott/Desktop/test-application-master 2"
    ]
  ],
  "_from": "angularfire2@>=2.0.0-beta.7 <3.0.0",
  "_id": "angularfire2@2.0.0-beta.7",
  "_inCache": true,
  "_location": "/angularfire2",
  "_nodeVersion": "6.9.1",
  "_npmOperationalInternal": {
    "host": "packages-12-west.internal.npmjs.com",
    "tmp": "tmp/angularfire2-2.0.0-beta.7.tgz_1484315670561_0.09154823864810169"
  },
  "_npmUser": {
    "name": "davideast",
    "email": "dceast@gmail.com"
  },
  "_npmVersion": "3.10.8",
  "_phantomChildren": {},
  "_requested": {
    "raw": "angularfire2@^2.0.0-beta.7",
    "scope": null,
    "escapedName": "angularfire2",
    "name": "angularfire2",
    "rawSpec": "^2.0.0-beta.7",
    "spec": ">=2.0.0-beta.7 <3.0.0",
    "type": "range"
  },
  "_requiredBy": [
    "/"
  ],
  "_resolved": "https://registry.npmjs.org/angularfire2/-/angularfire2-2.0.0-beta.7.tgz",
  "_shasum": "ce4f98467c5a8b2cc1dfd607fda718aee8d64521",
  "_shrinkwrap": null,
  "_spec": "angularfire2@^2.0.0-beta.7",
  "_where": "/Users/Scott/Desktop/test-application-master 2",
  "author": {
    "name": "jeffbcross,davideast"
  },
  "bugs": {
    "url": "https://github.com/angular/angularfire2/issues"
  },
  "dependencies": {},
  "description": "<p align=\"center\">   <h1 align=\"center\">AngularFire2</h1>   <p align=\"center\">The official library for Firebase and Angular 2</p> </p>",
  "devDependencies": {
    "@angular/compiler-cli": "^2.0.0",
    "@angular/platform-server": "^2.0.0-rc.5",
    "@types/jasmine": "^2.5.36",
    "@types/request": "0.0.30",
    "concurrently": "^2.2.0",
    "conventional-changelog-cli": "^1.2.0",
    "es6-module-loader": "^0.17.10",
    "es6-shim": "^0.35.0",
    "gulp": "^3.9.0",
    "gulp-jasmine": "^2.2.1",
    "gulp-typescript": "^2.10.0",
    "http-server": "^0.8.5",
    "jasmine": "^2.4.1",
    "jasmine-core": "^2.4.1",
    "json": "^9.0.3",
    "karma": "^0.13.19",
    "karma-chrome-launcher": "^0.2.2",
    "karma-firefox-launcher": "^0.1.7",
    "karma-jasmine": "^0.3.6",
    "karma-mocha-reporter": "^2.0.2",
    "karma-systemjs": "^0.10.0",
    "ncp": "^2.0.0",
    "parse5": "^1.3.2",
    "protractor": "3.0.0",
    "reflect-metadata": "0.1.2",
    "rimraf": "^2.5.4",
    "rollup": "^0.35.11",
    "rollup-watch": "^2.5.0",
    "systemjs": "^0.19.16",
    "systemjs-builder": "^0.15.7",
    "traceur": "0.0.96",
    "typedoc": "github:jeffbcross/typedoc",
    "typescript": "^2.0.2",
    "zone.js": "^0.7.2"
  },
  "directories": {},
  "dist": {
    "shasum": "ce4f98467c5a8b2cc1dfd607fda718aee8d64521",
    "tarball": "https://registry.npmjs.org/angularfire2/-/angularfire2-2.0.0-beta.7.tgz"
  },
  "homepage": "https://github.com/angular/angularfire2#readme",
  "keywords": [
    "angular2",
    "angular",
    "firebase"
  ],
  "license": "MIT",
  "main": "bundles/angularfire2.umd.js",
  "maintainers": [
    {
      "name": "angularcore",
      "email": "angular-core+npm@google.com"
    },
    {
      "name": "davideast",
      "email": "dceast@gmail.com"
    },
    {
      "name": "jeffbcross",
      "email": "middlefloor@gmail.com"
    }
  ],
  "module": "index.js",
  "name": "angularfire2",
  "optionalDependencies": {},
  "peerDependencies": {
    "@angular/common": "^2.0.0",
    "@angular/compiler": "^2.0.0",
    "@angular/core": "^2.0.0",
    "@angular/platform-browser": "^2.0.0",
    "@angular/platform-browser-dynamic": "^2.0.0",
    "firebase": "^3.0.0",
    "rxjs": "^5.0.1"
  },
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/angular/angularfire2.git"
  },
  "scripts": {},
  "typings": "index.d.ts",
  "version": "2.0.0-beta.7"
}

推荐答案

您应该创建一个LoginService

并分别登录和身份验证订阅.

And separate login and auth-subscription.

export class LoginService {

   public isLoggedIn = false;
   private _authSubsription;

   constructor(private _af: AngularFire) {
      this._authSubscription = this._af.auth.subscribe(auth => {
         if (!auth) {
            console.log('LOGGED OUT!!');
            this.isLoggedIn = false;
            return;
         }

         this.isLoggedIn = true;

         // do your stuff here ..
      });
   }

   public login() {
      this._af.auth.login({
         provider: AuthProviders.Facebook,
         method: AuthMethods.Popup,
         scope: ['public_profile']
      });
   }

   public logout() {
      this._af.auth.logout();
   }
}

请参阅我的分支机构: https://github.com/mxii/test-application

See my branch: https://github.com/mxii/test-application

和PR: https://github.com/Atkinson88/test-application/拉/1

您的LoginService存在一个问题.它实例化了两次,我不确定为什么.

There is an existing problem with your LoginService. Its instantiated twice, I am not sure why.

这篇关于AngularFire2登录注销订阅身份验证问题-Angular2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆