最近,我把我的工作程序,並把它轉換使用lazy loading
。現有的應用程序沒有問題,我使用Auth0
爲authentication
。當我運行應用程序時,轉換爲lazy loading
一切似乎運行正常。除了一個問題。
問題 -
當我點擊從Auth0 widget
登錄應用程序繼續進行正常。但是有兩件事發生。
Login
成功工作authentication
該用戶。Login
失敗,沒有錯誤。 當它失敗時,它轉發到auth0,然後快速重定向到主頁而不將該令牌保存到本地存儲。
我可以連續登出10次。 1的登錄將工作,那麼它將失敗9次10。我沒有提供任何錯誤消息或警告。我什至不能想出一種方法來解決這個問題,因爲有時它的工作原理,當它不工作,沒有任何改變,導致它失敗。
事情我已經試過了 -
然不使用
lazy loading
的應用。 完美作品從其他計算機上運行延遲加載應用程序。 存在問題
重新啓動的服務器。 存在問題
更改了回撥URL。 存在問題
問題 -
有誰知道的一個聰明的辦法來解決這個問題? 有誰知道什麼可能會導致這樣的事情發生?
代碼示例
app.module.ts
/* Routing Module */
import { AppRoutingModule } from './app-routing.module';
// Shared Stuff
import { SharedModule } from './shared/shared.module';
//Page Modules
import { HomeModule } from './home/home.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule,
AppRoutingModule,
HomeModule,
SharedModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
APP-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ApiKeyGuard } from "./shared/services/api.key.guard.service";
import { ProfileGuard } from "./shared/services/profile.guard.service";
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'benefits', loadChildren: './benefits/benefits.module#BenefitsModule' },
{ path: 'fcra', loadChildren: './fcra/fcra.module#FcraModule' },
{ path: 'croa', loadChildren: './croa/croa.module#CroaModule' },
{ path: 'tips', loadChildren: './tips/tips.module#TipsModule' },
{ path: 'maintenance', loadChildren: './maintenance/maintenance.module#MaintenanceModule' },
{ path: 'verify-email', loadChildren: './verify-email/verify-email.module#VerifyEmailModule' },
{ path: 'profile', canActivate: [ProfileGuard], loadChildren: './profile/profile.module#ProfileModule' },
{ path: 'recommendations', canActivate: [ApiKeyGuard], loadChildren: './recommendations/recommendations.module#RecommendationsModule' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }
/shared/shared.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
//Services
import { ApiKeyGuard } from './services/api.key.guard.service';
import { ProfileGuard } from './services/profile.guard.service';
import { Auth } from './services/auth.service';
@NgModule({
imports: [
CommonModule,
RouterModule,
FormsModule,
ReactiveFormsModule,
CollapseModule,
ChartsModule,
TabsModule.forRoot(),
ToastyModule.forRoot(),
SignaturePadModule,
],
declarations: [
HeaderComponent,
BreadcrumbsComponent,
FooterComponent,
LsideComponent,
RsideComponent,
NAV_DROPDOWN_DIRECTIVES,
SIDEBAR_TOGGLE_DIRECTIVES,
AsideToggleDirective
],
providers: [
ApiKeyGuard,
ProfileGuard,
Auth
],
exports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
RouterModule,
HeaderComponent,
BreadcrumbsComponent
]
})
export class SharedModule { }
breadcrumb是共享目錄中的共享組件。該組件呈現在網站上出現的每個頁面中,並被注入到app.component.ts
和app.component.html
。
將auth服務注入到麪包屑組件中。
import { Component } 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 {
constructor(private router:Router, private route:ActivatedRoute, private auth: Auth) {}
ngOnInit(): void { }
}
來自auth.service的登錄功能在breadcrumb.component.html文件中調用。
breadcrumb.component.html
<a class="nav-link" (click)="auth.login()" *ngIf="!auth.authenticated()">Login/SignUp</a>
驗證服務
import { Injectable } from '@angular/core';
import { tokenNotExpired, JwtHelper } from 'angular2-jwt';
import { Router } from '@angular/router';
import { myConfig } from './auth.config';
import {Http, Response, Headers, URLSearchParams} from '@angular/http';
import { User } from './../models/user';
import { LogReg } from './../models/logreg';
import { STATICS } from './../static/static';
declare var Auth0Lock: any;
var options = {
theme: {
logo: 'assets/img/logo.png',
primaryColor: '#779476'
},
languageDictionary: {
emailInputPlaceholder: "[email protected]",
title: "Login or SignUp"
},
};
@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();
}
private get accessToken(): string {
return localStorage.getItem('access_token');
}
private get apiKey(): string {
var apiKey = JSON.parse(localStorage.getItem('api_key'));
return apiKey
}
public authenticated(): boolean {
try {
var jwtHelper: JwtHelper = new JwtHelper();
var token = this.accessToken;
if (jwtHelper.isTokenExpired(token))
return false;
return true;
}
catch (err) {
return false;
}
}
public logout() {
var apiKeyExist = this.user.api_key_exist;
console.log(apiKeyExist);
if (apiKeyExist === true) {
let params: URLSearchParams = new URLSearchParams();
params.set('email', this.user.email);
params.set('api_key', this.apiKey);
localStorage.removeItem('profile');
localStorage.removeItem('api_key');
localStorage.removeItem('access_token');
localStorage.removeItem('user');
this.userProfile = null;
this.user = null;
this.router.navigateByUrl('/home');
return this.http.get(STATICS.API_BASE + STATICS.API_LOGOUT,
{ search: params })
.map((res: Response) => res.json())
.subscribe((res) => {
console.log(res);
this.user = null;
console.log(this.user);
});
} else {
localStorage.removeItem('profile');
localStorage.removeItem('api_key');
localStorage.removeItem('access_token');
localStorage.removeItem('user');
this.userProfile = null;
this.user = null;
this.router.navigateByUrl('/home');
}
};
}
******************** UPDATE **** ********************* 在shared.module.ts我做了一個改變。
我改變了出口這在文件的底部,
export class SharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [Auth]
};
}
}
現在我已經能夠登錄和註銷5次連續成功。但用戶的圖像並未顯示auth0響應提供的圖像。我現在想知道它是否仍然有點不好,因爲我需要確保在正確的位置指定forRoot和forChild。
我指定了app-routing.moduel.ts文件中的所有路徑,它位於應用程序的根目錄中,可以在上面的代碼中看到。
在每個延遲加載的模塊中都有一個路由文件。這裏是家庭路線的一個例子文件
家庭routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home.component';
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full'},
{ path: 'home', component: HomeComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class HomeRoutingModule {}
注意,forChild是在RouterModule。
配置是否正確?我也應該將shared.module.ts添加到每個模塊或只?
能否請您提供一些小的代碼段,你的延遲加載是如何在你的路由配置,以及您導入或提供您的身份驗證服務?包括您的角度版和路由器。 另外,請您詳細說明第2種情況下發生的具體情況,發生故障時無誤嗎?你沒有被Auth0重定向,你沒有獲得令牌,或者**它看起來如何「失敗」?** – jgranstrom
我按照你的要求更新了我的問題。我向2號場景添加了解釋,並添加了解釋該過程的所有代碼。如果你能幫我解決這個問題,我將不勝感激。我甚至無法弄清楚如何排除故障。我在驗證服務中使用console.log。當登錄工作時,console.log起作用。當登錄不起作用時,console.log不會輸出。所以有時候authservice有效,有時不會。 – wuno
我沒有看到您的身份驗證和延遲加載之間的連接。從你的代碼看起來''Auth'服務是被急切加載的(通過'SharedModule'),所以它不應該被懶惰地加載一堆* other模塊所影響。你能否確認**所有認證相關的任務**在Auth服務**中執行**並且此服務不是延遲加載的? – AngularChef