我正在尝试通过PassportJS限制对客户端Angular应用的访问。
基本上我正试图路由任何试图访问该应用程序的人重定向到身份验证提供程序进行登录。但似乎角度路线覆盖了NodeJS Express路线。
所以如果我去'/'它只会加载角度应用程序而不是重定向它们。对于使用与角度路线相同路线的每条路线,情况都是相同的。
server.js片段:
以下代码应重定向所有人登录Facebook。但它只是加载角度索引页面。
function checkAuthentication(req,res,next){
if(req.isAuthenticated()){
//if user is looged in, req.isAuthenticated() will return true
console.log("/ " + true);
res.sendFile(path.join(__dirname, 'dist/index.html'));
} else{
console.log("/ " + false);
res.redirect("/api/passport/login/facebook");
}
}
app.get('/*', checkAuthentication ,(req, res) => {
});
Angular index.html代码段:
index.html页面使用与快速路由器中显示的路由相同的路由。
<base href="/">
假设我将index.html base href更改为使用'/ app /',如下所示:
<base href="/app/">
并在express中设置路由,将登录用户重定向到'/ app /',如下所示:
angular.route示例:
app.use("/app", express.static(path.join(__dirname, 'dist')));
function checkAuthentication(req,res,next){
if(req.isAuthenticated()){
//if user is looged in, req.isAuthenticated() will return true
console.log("/app" + true);
res.sendFile(path.join(__dirname, '../../dist/index.html'));
} else{
console.log("/app" + false);
res.redirect("/api/passport/login/facebook");
}
}
router.get('/app', checkAuthentication, (req, res) => {
console.log("approuter hit");
});
module.exports = router;
直接转到'/ app'。它仍然会加载angular index.html页面而不是重定向您登录。但是如果你转到'/'它会重定向你登录。
如何阻止角度超越我的NodeJS快速路线?
更新:
app.route.js片段:
import { Routes } from '@angular/router';
import { HomeComponent } from './home';
export const ROUTES: Routes = [
{ path: '', component: HomeComponent },
];
答案 0 :(得分:2)
您必须在客户端(即Angular)实施AuthGuard和身份验证服务,它将充当客户端和服务器之间的通信器。还要保留像isAuthenticated这样的变量来跟踪登录状态。
AuthGuard:
import { Injectable } from '@angular/core';
import { CanActivate, CanActivateChild, Router } from '@angular/router';
import { AuthenticationService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthenticationService, private router: Router) {}
canActivate() : boolean {
console.log('AuthGuard#canActivate called ' + this.authService.isAuthenticated );
return this.checkLoggedIn("random");
}
canActivateChild() : boolean {
return this.canActivate();
}
checkLoggedIn(url: string): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.authService.redirectUrl = url;
this.router.navigate(['/login']);
return false;
}
}
的AuthenticationService:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Observable } from 'rxjs/Rx';
import { NgForm } from "@angular/forms";
import { AuthenticationApi } from "../../modules/authentication/authentication-api";
import { IUser } from "app/modules/authentication/user";
var headers = new Headers({ 'Content-Type': 'application/json' });
var options = new RequestOptions({ headers: headers });
@Injectable()
export class AuthenticationService implements AuthenticationApi {
currentUser: IUser;
redirectUrl: string;
changePassoword: () => Observable<any>;
forgotPassowrd: () => Observable<any>;
isAuthenticated = false;
constructor(private router: Router, private http: Http) {
this.currentUser = null
}
isLoggedIn(): boolean {
return !!this.currentUser;
}
logIn(logInUser:any): Observable<any> {
console.log('UserService.signIn: ' + logInUser.userName + ' ' + logInUser.password + ' ' + logInUser.rememberMe);
this.isAuthenticated = true;
this.currentUser = {
userName: logInUser.userName
}
return this.http.post('http://localhost:3000/auth/login',
JSON.stringify(logInUser),
options
)
.map((resp: Response) => resp.json())
.catch(this.handleError);
//return Observable.of({}).delay(2000);
// return Observable.of({}).delay(2000).flatMap(x=>Observable.throw('Invalid User Name and/or Password'));
}
register(registerUser:any): Observable<any> {
this.isAuthenticated = true;
console.log(registerUser);
return this.http.post('http://localhost:3000/auth/register',
JSON.stringify(registerUser),
options
)
.map((resp: Response) => resp.json())
.catch(this.handleError);
//this.router.navigate(['/signin']);
//return Observable.of({}).delay(2000);
}
connectWithFacebook() :Observable<any> {
this.isAuthenticated = true;
//return Observable.of({}).delay(2000);
return this.http.get('http://localhost:3000/auth/facebook')
.map((resp: Response) => resp.json())
.catch(this.handleError);
}
connectWithGoogle() :Observable<any> {
this.isAuthenticated = true;
//return Observable.of({}).delay(2000);
return this.http.get('http://localhost:3000/auth/google')
.map((resp: Response) => resp.json())
.catch(this.handleError);
}
handleError(error: any) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
logOut(): Observable<any>{
this.isAuthenticated = false;
this.currentUser = null;
this.router.navigate(['/login']);
return Observable.of({})
}
}
AuthenticationApi:沟通的常用方法
import { Observable } from 'rxjs';
export abstract class AuthenticationApi {
logIn : (loginUser:any) => Observable<any>;
logOut : () => Observable<any>;
register : (registerUser:any) => Observable<any>;
connectWithFacebook : () => Observable<any>;
connectWithGoogle : () => Observable<any>;
changePassoword : () => Observable<any>;
forgotPassowrd : () => Observable<any>;
}