在 Gravatar 存在之前使用 Auth0 重定向的 Angular2 Auth
Angular2 Auth With Auth0 Redirecting Before Gravatar Exist
背景
在我的 angular2
应用程序中,我使用 Auth0
到 authenticate
。在 redirect
回到我的网站后,我在 component
中向他们显示一些用户的 data
。当页面 renders
它不显示用户的 email
或 gravatar
/图像。但此时如果我刷新页面,gravatar
和 email
就会显示。
设置
在 app.component.html 中,我直接在导航下方添加面包屑组件,但直接在 router-outlet
.
之上
面包屑显示在每一页上。如果有人没有登录,它会显示 Login / Register
link。如果有人登录,它应该显示用户的照片和他们的电子邮件,这些电子邮件在保存到 localStorage
的 auth0
profile
中返回。
在呈现给 router-outlet
的组件内,localStorage
中的所有数据都显示在页面中。此页面呈现完美。但是 breadcrumb
component
没有更新 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
功能以多种不同方式验证和分配数据。
breadcrumb.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();
}
}
问题
当有人登录时,我如何在完成页面呈现之前确保数据存在?这样我可以确保向用户显示正确的数据。
我不能评论我会写这个作为答案。
我有同样的问题,我这样做解决了它:
编辑
试试这个:
首先,我使用这个让生活变得轻松的自定义事件发射器:
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 中,我有:
<li><a [hidden]="!username" *ngIf="auth.authenticated()">Welcome, {{username}}</a></li>
希望对您有所帮助!
背景
在我的 angular2
应用程序中,我使用 Auth0
到 authenticate
。在 redirect
回到我的网站后,我在 component
中向他们显示一些用户的 data
。当页面 renders
它不显示用户的 email
或 gravatar
/图像。但此时如果我刷新页面,gravatar
和 email
就会显示。
设置
在 app.component.html 中,我直接在导航下方添加面包屑组件,但直接在 router-outlet
.
面包屑显示在每一页上。如果有人没有登录,它会显示 Login / Register
link。如果有人登录,它应该显示用户的照片和他们的电子邮件,这些电子邮件在保存到 localStorage
的 auth0
profile
中返回。
在呈现给 router-outlet
的组件内,localStorage
中的所有数据都显示在页面中。此页面呈现完美。但是 breadcrumb
component
没有更新 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
功能以多种不同方式验证和分配数据。
breadcrumb.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();
}
}
问题
当有人登录时,我如何在完成页面呈现之前确保数据存在?这样我可以确保向用户显示正确的数据。
我不能评论我会写这个作为答案。 我有同样的问题,我这样做解决了它:
编辑
试试这个:
首先,我使用这个让生活变得轻松的自定义事件发射器:
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 中,我有:
<li><a [hidden]="!username" *ngIf="auth.authenticated()">Welcome, {{username}}</a></li>
希望对您有所帮助!