我的代码如下所示,我正在为我的应用程序使用第三方登录(openAM)。每当我收到401消息时,都应将应用程序重定向到另一个URL,然后该用户将登录。
我使用http拦截器检查状态并重定向到登录。 问题1:这种方法正确吗?
问题2:没有翻译。
检查 handleHttpResponseCodes 方法。在这种情况下,“ unauthorizedMessage”没有翻译。不仅任何消息都没有翻译。我的代码有什么问题。
import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { AuthService } from 'app/blocks/auth/auth.service';
import { TranslateService } from 'ng2-translate';
import { AlertService } from '../../core/services/common';
import { Router } from '@angular/router';
import * as jsToaster from 'toastr';
@Injectable()
export class AppHttpInterceptor implements HttpInterceptor {
constructor(
private injector: Injector,
private router: Router,
private translate: TranslateService
) {}
intercept(req: HttpRequest < any > , next: HttpHandler): Observable < HttpEvent < any >> {
// console.log(req);
if (!window.navigator.onLine) {
// check to see if there's internet
// if there is no internet, throw a HttpErrorResponse error
// since an error is thrown, the function will terminate here
return Observable.throw(new HttpErrorResponse({
error: 'NO_INTERNET'
}));
} else {
// else return the normal request
return this.handleResponse(next, req);
}
}
handleResponse(next, req) {
return next.handle(req)
.do((ev: HttpEvent < any > ) => {
if (ev instanceof HttpResponse) {
//console.log('ev in the do: ', ev);
}
})
.catch((response: any) => {
if (response instanceof HttpErrorResponse) {
this.handleHttpResponseCodes(response);
} else {
console.log('::UNKNOWN ERROR::', response);
}
return Observable.throw(response);
});
}
handleHttpResponseCodes(exception) {
let authService = this.injector.get(AuthService);
let translate = this.injector.get(TranslateService);
let alertService = this.injector.get(AlertService);
const router = this.injector.get(Router);
switch (exception.status) {
case 401: //UNAUTHORIZED
debugger;
this.translate.get('unauthorisedMessage').subscribe((res: string) => {
debugger;
**//ISSUE: TRANSLATION NOT HAPPENING WHY? //**
this.showToast(res, '401');
});
setTimeout(() => {
authService.login_openAM();
}, 3000);
break;
case 400: //BAD REQUEST OR FR SESSION TIME OUT
this.translate.get('loginSessionExpiredMessage').subscribe((res: string) => {
debugger;
this.showToast(res, '400');
});
setTimeout(() => {
authService.loginSessionExpired();
}, 2000);
break;
case 403: // FORBIDDED ACCESS
//TODO
break;
case 502: // BAD GATEWAY
break;
case 503: //SERVICE UNAVAILABLE
jsToaster.error("SERVICE UNAVAILABLE", "503");
break;
case 504: //GATEWAY TIMEOUT
jsToaster.error("SERVICE UNAVAILABLE", "CODE:504-GATEWAY TIMEOUT");
break;
}
console.log(':Service Exception::', exception);
}
showToast(title, body, typeOfToast, waitTime) {
setTimeout(() => {
jsToaster[typeOfToast](body, title);
}, waitTime);
}
}
AppLoadService
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';
import { APP_SETTINGS } from 'app/app-settings/settings';
import { AlertService } from '../core/services/common';
@Injectable()
export class AppLoadService {
constructor(
private httpClient: HttpClient,
private alertService: AlertService
) { }
load(): Promise<any> {
console.log('@started step1');
return new Promise(resolve => {
const promise = this.httpClient.get('assets/settings/config.json') // CONTAINS APPLICATION LOGIN AND LOGOUT URL PATHS
.subscribe(
res_config => {
console.log('@config json loaded step2');
APP_SETTINGS.app_login_url = res_config["app_login_url"] || res_config["app_LOGIN_URL"];
APP_SETTINGS.app_logout_url = res_config["app_logout_url"] || res_config["app_LOGOUT_URL"];
console.log("::initializeApp:config file loaded");
/*=========== AUTH API - START ===========*/
this.httpClient.get('/XXXX/v2/authentication-api')
.subscribe(
res_auth_context => {
this.storeUserContext(res_auth_context);
console.log('@auth context loaded step3');
/*=========== LOAD PRODUCTS ===========*/
this.httpClient.get('/XXXX/v1/api/lab')
.subscribe(
res_products => {
console.log('@auth context loaded step4');
APP_SETTINGS.isproductsLoaded = true;
APP_SETTINGS.appproducts = res_products;
console.log("::initializeApp:: products Loaded");
resolve();
},
res_products_error => {
console.log("::initializeApp:: products NOT Loaded", res_products_error);
resolve();
}
);
/*=========== LOAD products ===========*/
},
res_auth_context_error => {
console.log("Auth Call Failed");
}
);
/*=========== AUTH CONTEXT CALL API - END ===========*/
},
res_config_Error => {
console.log("::initializeApp:config file NOT loaded", res_config_Error);
}
);
});
}
storeUserContext(usetContext: any): any {
sessionStorage.setItem("AUTH_TOKEN", JSON.stringify(usetContext));
}
}
APP MODULE
export function createTranslateLoader(http: Http) {
return new TranslateStaticLoader(http, './assets/i18n', '.json');
}
@NgModule({
declarations: [
AppComponent, CustomDateRangePickerComponent
],
imports: [
// :CORE MODULE: //
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
TranslateModule.forRoot(
{
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}),
FormsModule,
CommonModule, //<====added
//:3RD PARTY MODULE://
BootstrapModalModule,
//:APPLICTION MODULES: //
AppLoadModule, //Startupdata before APP loaded
AppRoutingModule,
FooterModule,
ErrorModule,
AccessDeniedModule,
NotFoundModule,
RouterModule.forRoot([]),
ToasterModule.forChild(),
],
providers: [
LoaderService,
ToasterService,
StartupService,
ResponseStatusesService,
LocalStorageService,
ApplicationSettingsService,
LabSelectionService,
AccountService,
AuthService,
AlertService,
AuthGuard,
RolesGuard,
FeaturebasedGuard,
ErrorLogService,
{
provide: ErrorHandler,
useClass: GlobalErrorsHandler
},
{
provide: HTTP_INTERCEPTORS,
useClass: AppHttpInterceptor,
multi: true
},
{
provide: LocationStrategy,
useClass: HashLocationStrategy
},
],
exports: [],
bootstrap: [AppComponent]
})
export class AppModule { }
家庭组件
export class HomeComponent implements OnInit {
constructor(private loaderService: LoaderService, private translate: TranslateService,
private router: Router,
private AuthService: AuthService,
private AlertService: AlertService,
) { }
ngOnInit() {
if (this.AuthService.isUserLoggedIn()) {
let userDetails = this.AuthService.getUserDetails();
if (userDetails) {
let redirect_path = this.routeResolver(userDetails);
//=>ROUTE TO REDIRECT BASED ON LOGGED IN USER ROLE<=//
this.router.navigate([redirect_path]);
} else {
this.AlertService.error("invalidUserDetailsRecieved", "home comp");
}
}
}
警报服务(我正在使用angular2烤面包机)
import { Injectable } from "@angular/core";
import { Fault } from "../../models/fault";
import { ToasterService, Toast } from "angular2-toaster";
import { TranslateService, LangChangeEvent } from "ng2-translate";
@Injectable()
export class AlertService {
constructor(
private toastyService: ToasterService,
private translate: TranslateService,
) { }
success(title: string, message: string): void {
this.translate.get([title, message]).subscribe(res => {
this.showToast(res[title], res[message], "success");
});
}
info(title: string, message: string): void {
this.translate.get([title, message]).subscribe(res => {
this.showToast(res[title], res[message], "info");
});
}
warning(title: string, message: string): void {
let toastBlock = () => {
this.translate.get([title, message]).subscribe(res => {
this.showToast(res[title], res[message], "warning");
});
}
this.triggerToastWithMessage(toastBlock);
}
error(title: string, message: string): void {
let toastBlock = () => {
this.translate.get([title, message]).subscribe(res => {
this.showToast(res[title], res[message], "error");
});
}
this.triggerToastWithMessage(toastBlock);
}
fault(fault: Fault): void {
this.showToast("", fault.message, "error");
}
showToast(title, body, type) {
var toast: Toast = <Toast>{
title: title,
body: body,
type: type
};
this.toastyService.pop(toast);
}
triggerToastWithMessage(fn) {
setTimeout(() => {
fn();
}, 500);
}
}
AppRoutingModule
const routes: Routes = [
{
path: '',
children: [
{ path: '', loadChildren: './home/home.module#HomeModule' },
{ path: 'error', loadChildren: './core/error/error.module#ErrorModule' },
{ path: 'accessDenied', loadChildren: './accessDenied/access-denied.module#AccessDeniedModule' },
{ path: 'notfound', loadChildren: './notFound/not-found.module#NotFoundModule' },
{ path: '**', redirectTo: '/notfound' }
]
}
];
@NgModule({
declarations: [],
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
HomeRoutingModule
const routes: Routes = [
{
path: '',
canActivate: [AuthGuard],
component: HomeComponent,
children: [
{
path: 'job-search',
loadChildren: '../job-search/job-search.module#JobSearchModule',
canActivate: [RolesGuard],
data: {
roles: permitted_roles.JOB_SEARCH,
router_name: routerNames.JOB_SEARCH,
}
},
-------------
-------------
AuthGaurd
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private AuthService: AuthService,
private AlertService: AlertService,
private ResponseStatusesService: ResponseStatusesService
) {
console.log('AuthGuard Constructor Executed');
}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
console.log("Authgaurd can activate");
if (this.AuthService.isUserLoggedIn()) {
debugger;
return true;
}
return false;
}
}
Auth Service
public isUserLoggedIn(): boolean {
const token = sessionStorage.getItem("AUTH_TOKEN");
if (token) {
return true;
} else {
return false;
}
}
答案 0 :(得分:0)
此外,请尝试明确地使用区域设置代码:
this.translate.use('en-EN');
答案 1 :(得分:0)
基本上,您的做法正确。 但是拦截器应该是这样的:
import { Injectable } from '@angular/core';
import { HttpHandler, HttpEvent, HttpRequest, HttpErrorResponse, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from "rxjs/operators";
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((err: HttpErrorResponse, caught: Observable<any>) => {
switch(err.status){
case 404:
return throwError('Errors.404');
default:
return throwError('Errors.500')
}
})
);
}
}
在此实现中,您只需返回错误的 本地化令牌 。
在subscription
上,您应处理以下错误:
.subscribe((result: any) => {
... success result here ...
}, error => {
this.error = error; <--- this what you need
});
在HTML
模板上,只需使用translate
管道进行本地化:
<div>{{error|translate}}</div>
答案 2 :(得分:0)
请确保您设置了翻译服务并正确提供了拦截器。这对我有用:
// app.module.ts
@NgModule({
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: AppHttpInterceptor,
multi: true,
deps: [ AuthService, TranslateService, AlertService, Router ]
}],
// ...
})
export class AppModule {
constructor(translateService: TranslateService, localStorage: LocalStorageService) {
translateService.addLangs(SUPPORTED_LANGS);
translateService.setDefaultLang(DEFAULT_LANG);
// Use either the lang stored in browser local storage...
const useLang: string = localStorage.getLang()
// ...the browser language if supported...
|| SUPPORTED_LANGS.find(lang => lang === translate.getBrowserLang())
// ...or the default language
|| DEFAULT_LANG;
translate.use(useLang)
.pipe(takeWhile(() => this.componentActive), switchMap(() => translate.onLangChange))
// Update the local storage on language change
.subscribe((e: TranslationChangeEvent) => localStorage.setLang(e.lang));
}
// ...
}
// app-http.interceptor.ts
export class AppHttpInterceptor implements HttpInterceptor {
constructor(private authService: AuthService,
private translateService: TranslateService,
private alertService: AlertService,
private router: Router) {
// ...
}
// ...
}
希望这会有所帮助:-)