【问题标题】:Angular2 Auth With Auth0 Redirecting Before Gravatar Exist在 Gravatar 存在之前使用 Auth0 重定向的 Angular2 Auth
【发布时间】:2017-07-21 08:24:57
【问题描述】:

背景

在我的angular2 应用程序中,我使用Auth0authenticate。在redirect 回到我的网站后,我在component 中向他们显示一些用户的data。当页面renders 不显示用户的emailgravatar / 图像。但此时如果我刷新页面,gravataremail 会显示。

设置

在 app.component.html 中,我直接在导航下方添加面包屑组件,但直接在 router-outlet 顶部。

面包屑显示在每一页上。如果有人没有登录,它会显示一个Login / Register 链接。如果有人登录,它应该显示用户的图片和他们的电子邮件,该电子邮件在auth0profile 中返回,并保存到localStorage

在渲染到router-outlet 的组件内部,localStorage 中的所有数据都显示在页面中。此页面完美呈现。但是breadcrumbcomponent 不会使用来自localStorage 的正确数据进行更新。

很明显,这里的问题是breadcrumb component 正在被渲染,而localStorage 中的profile 仍然是null

代码示例

我是这样显示数据的,

breadcrumb.component.html

<ul class="nav navbar-nav pull-right" *ngIf="!auth.authenticated()">
  <li class="nav-item">
    <a class="nav-link" (click)="auth.login()">Login / SignUp</a>
  </li>
</ul>

<ul class="nav navbar-nav pull-right" *ngIf="auth.authenticated()">
  <li class="nav-item">
    <a class="aside-toggle" href="#" role="button" aria-haspopup="true" aria-expanded="false">

      <span *ngIf="auth.userProfile.nickname" class="profile-name">{{auth.userProfile.nickname}}</span>
      <span *ngIf="!auth.userProfile.nickname" class="profile-name">Account</span>

      <i class="icon-bell"></i><span class="tag tag-pill tag-danger profile-alerts">5</span>

      <img *ngIf="auth.userProfile.picture" [src]="auth.userProfile.picture" class="img-avatar profile-picture" alt="User profile picture">
      <img *ngIf="!auth.userProfile.picture" src="assets/img/avatars/gravatar-default.png" class="img-avatar profile-picture" alt="Default profile-picture">

    </a>
  </li>
</ul>

请注意,我已尝试使用内置 NG2 功能以多种不同方式验证和分配数据。

面包屑.component.ts

import { Component, OnInit, AfterViewInit, OnChanges } from '@angular/core';
import { Router, ActivatedRoute }    from '@angular/router';
import { Auth }                      from './../services/auth.service';

@Component({
    selector: 'breadcrumbs',
    templateUrl: './breadcrumb.component.html'
})
export class BreadcrumbsComponent implements OnInit, AfterViewInit, OnChanges {
  private gravatar: string
  private email: string;

  constructor(private router:Router, private route:ActivatedRoute, private auth: Auth) {
      if (this.auth.authenticated()) {
        var userProfile = JSON.parse(localStorage.getItem('profile'));
        this.gravatar = userProfile.picture;
        this.email = userProfile.email;
      }
    }

  ngOnChanges() {
    if (this.auth.authenticated()) {
      var userProfile = JSON.parse(localStorage.getItem('profile'));
      this.gravatar = userProfile.picture;
      this.email = userProfile.email;
    }
  }

  ngOnInit() {
    if (this.auth.authenticated()) {
      var userProfile = JSON.parse(localStorage.getItem('profile'));
      this.gravatar = userProfile.picture;
      this.email = userProfile.email;
    }
  }

  ngAfterViewInit() {
    if (this.auth.authenticated()) {
      var userProfile = JSON.parse(localStorage.getItem('profile'));
      this.gravatar = userProfile.picture;
      this.email = userProfile.email;
    }
  }
}

当我检查本地存储时,数据确实存在。所以这让我相信页面在数据能够被放置在本地存储之前呈现。

这是我auth0 service 的大部分内容。

authorize.service.ts

@Injectable()
export class Auth {
  lock = new Auth0Lock(myConfig.clientID, myConfig.domain, options, {});
  userProfile: Object;
  logreg: LogReg;
  user: User;

  constructor(private router: Router, private http: Http ) {

    this.userProfile = JSON.parse(localStorage.getItem('profile'));
    this.user = JSON.parse(localStorage.getItem('user'));
    this.lock.on('authenticated', (authResult: any) => {
      localStorage.setItem('access_token', authResult.idToken);
      this.lock.getProfile(authResult.idToken, (error: any, profile: any) => {
        if (error) {
          console.log(error);
          return;
        }

          // Login Or Register User On Our Server
        this.logreg = new LogReg(profile.email_verified, profile.email);

        this.checkRegister(this.logreg).subscribe(
            (res)=>{
              console.log("Hey this runs");
              console.log(res);
                if (res.email_verified === false) {
                 localStorage.removeItem('profile');
                 localStorage.removeItem('api_key');
                 localStorage.removeItem('access_token');
                 localStorage.removeItem('user');
                 this.userProfile = null;
                 this.user = null;
                 this.router.navigate(['/verify-email']);

                }
            else if (res.api_key_exist === false) {
                  console.log("Hey this works")
                localStorage.setItem('profile', JSON.stringify(profile));
                this.userProfile = profile;
                console.log(this.userProfile);
                this.user = new User(profile.email, '', '', '', '', '', '', '', '', '', '', res.api_key_exist, '')
                localStorage.setItem('user', JSON.stringify(this.user));
                this.router.navigate(['/profile']);

            } else if (res.api_key_exist === true) {
                this.user = new User(res.user.email,
                    res.user.first_name,
                    res.user.middle_name,
                    res.user.last_name,
                    res.user.dob,
                    res.user.phone,
                    res.user.street_address,
                    res.user.city_address,
                    res.user.state_address,
                    res.user.zip_address,
                    res.user.client_ss,
                    res.api_key_exist,
                    res.api_key);
                console.log(this.user);
                localStorage.setItem('api_key', JSON.stringify(res.api_key));
                localStorage.setItem('user', JSON.stringify(this.user));
                localStorage.setItem('profile', JSON.stringify(profile));
                this.router.navigate(['/overview']);
            }
        },
            (err)=>{ console.log(err);}

        );
      });
      this.lock.hide();
    });
  }

  public checkRegister(model: LogReg) {
      // Parameters obj-
      let params: URLSearchParams = new URLSearchParams();
      params.set('email', model.email);
      params.set('email_verified', model.email_verified);

      return this.http.get(STATICS.API_BASE + STATICS.API_LOGIN,
          { search: params }).map((res:Response) =>  res.json());
      }

  public login() {
    this.lock.show();
  }
}

问题

当有人登录时,我将如何在完成页面呈现之前确保数据存在?这样我可以确保向用户显示正确的数据。

【问题讨论】:

    标签: angular auth0


    【解决方案1】:

    我无法发表评论,我会写这个作为答案。 我有同样的问题,我解决了这个问题:

    编辑

    试试这个:

    首先我使用了这个让生活变得简单的自定义事件发射器:

    import { Injectable, EventEmitter } from '@angular/core';
    @Injectable()
    export class EmitterService {
       private static _emitters: { [ID: string]: EventEmitter<any> } = {};
    
       static get(ID: string): EventEmitter<any> {
          if (!this._emitters[ID]) 
            this._emitters[ID] = new EventEmitter();
          return this._emitters[ID];
        }
    
     }
    

    在 auth.service 内部:

    constructor(private auth: Auth, private issuesService: IssuesService) {
    if (this.auth.authenticated()){
        this.userProfile = this.auth.getProfile()
        this.username = this.userProfile.name
    }
    else {
      this.loadUserDetails().subscribe(_ => {
        this.username= this.userProfile.name 
      })
      }
     }
    
     ngOnInit() {
      if (this.auth.authenticated()){
        this.userProfile = this.auth.getProfile()
        this.username = this.userProfile.name
        console.log(this.username)
     }
     else {
      this.loadUserDetails().subscribe(_ => {
        this.username= this.userProfile.name 
      })
    }
    }
    
    loadUserDetails(){
     return EmitterService.get('USER_LOGGED_IN').map(userProfile => { 
        this.userProfile= userProfile
      });
    }
    

    在我的 html 中,我有:

    &lt;li&gt;&lt;a [hidden]="!username" *ngIf="auth.authenticated()"&gt;Welcome, {{username}}&lt;/a&gt;&lt;/li&gt;

    希望这会有所帮助!

    【讨论】:

    • 谢谢哥们,我去看看
    • 嘿,伙计,我更新了我的问题,向您展示我做了什么。这些都没有帮助。我不明白为什么。面包屑组件是应用程序模板的一部分。在 app.component 中调用。 html。在我添加延迟加载之前我没有这个问题。你认为我需要将它添加到每个延迟加载的组件而不是面包屑组件中吗?
    • 是的,所以我可以在本地存储的概览组件中输出日期。但是面包屑组件显然没有使用更新的数据重新渲染。我会通读您的编辑。
    • 是的,但这基本上就是您的身份验证服务所做的。如果用户已经通过身份验证,它会从本地存储中获取数据。除非令牌已过期。
    • 但是我的服务在经过身份验证时会将数据设置在本地存储中。并用数据更新组件。但是面包屑直到页面刷新后才会更新。有没有办法在用户登录后强制面包屑组件重新渲染?
    猜你喜欢
    • 2016-04-05
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    相关资源
    最近更新 更多