【问题标题】:Deciding between various methods for authentication in Angular 4在 Angular 4 中选择各种身份验证方法
【发布时间】:2017-11-15 23:39:41
【问题描述】:

我已经阅读了两个在 Angular 4 中实现身份验证的教程。

first 覆盖 RouterOutlet 类,并声明不需要登录的公共路由。

不过,second 方法是使用 Angular 4 提供的 canActivate AuthGuard 接口。
我正在努力找出哪种方法是正确或有效的方法。

此外,如何在 Angular 4 中实现授权。我阅读了 canActivateChild 接口,但似乎太复杂了。

【问题讨论】:

  • 第二种方法效果最好,您可以直接在路由文件中添加警卫。

标签: angular jwt


【解决方案1】:

我建议你使用AuthGuard

以下是一个如何实现 AuthGuard 的简单示例。

Module.ts

// Routes
const routes : Routes = [
{
    path: '',
    component: HomeComponent,
    canActivate : [AuthService] //<== Activate AuthGuard
},
{
    path: 'login',
    component: LoginComponent
},
{
    path: '**',
    redirectTo: ''
}
];
'

@NgModule({
    declarations: [
    AppComponent,
    LoginComponent,
    HomeComponent
    ],
    providers: [AuthService], //<== Add AuthService here
    bootstrap: [AppComponent]
})

AuthService

import { Injectable }     from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot }    from '@angular/router';

@Injectable() 
export class AuthService implements CanActivate {

    constructor(private router: Router) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let url: string = state.url; //<== Get URL if needed

        if (localStorage.getItem('token')) { // <== Check for token
            return true;
        }else {
            this.router.navigate(['/login']);
            return false;
        }
    }
}

【讨论】:

  • 非常感谢您的建议和代码。我添加了两个警卫,一个用于授权,另一个用于身份验证。我不确定我的实现是否正确?我在答案中提供了我的实现代码。该实现是否正确或者我应该如何更改它? (我在后端使用会话,而不是 jwt)。
【解决方案2】:

我写了两个Guard,一个用于实现身份验证,另一个用于授权。

//Guard for Authentication
@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private loginService: LoginService, private router: Router) { }
    canActivate() {
      if(this.loginService.isLoggedIn()){
        return true;
      }
      this.router.navigate(['/home']);
      return false;
    }
}

//Guard for Authorization
@Injectable()
export class AdminAuthGuard implements CanActivate {
    constructor(private loginService: LoginService, private router: Router) { }
    canActivate() {
      return this.loginService.checkSession().map(res=>{
            let resJSON = res.json();
            let isAllowed = (resJSON.length > 0 && resJSON[0].authority === "ROLE_ADMIN") ? true : (this.router.navigate(['/home']), false);
            return isAllowed;
          });
    }
}

这个实现是正确的,还是我应该遵循其他的? (虽然它工作正常,但我正在寻找更好的方法)。
我的应用程序的路由文件如下:

const appRoutes: Routes = [
    {
        path: '',
        redirectTo: '/home',
        pathMatch: 'full'
    },
    {
        path: 'home',
        component: HomeComponent
    },
    {
        path: 'adminPage',
        component: MyAccountComponent,
        canActivate: [AuthGuard, AdminAuthGuard] 
    }
];  

所以,每当我以管理员身份登录时,我都可以访问 adminPage,而如果我以普通用户身份登录,则无法访问网页。

loginService 实现如下:

//Login Service
@Injectable()
export class LoginService {
  private serverPath:string = AppConst.serverPath; //'http://127.0.0.1:8888'
  constructor(private http:Http, private router:Router) { }
  isLoggedIn() {
      return localStorage.getItem('xAuthToken') !== null;
    }
  //Server will send back the Token for the user.   
  sendCredential(username: string, password: string) {
    let url = this.serverPath+'/token';
    let encodedCredentials = btoa(username+":"+password);
    let basicHeader = "Basic "+encodedCredentials;
    let headers = new Headers({
        'Content-Type' : 'application/x-www-form-urlencoded',
        'Authorization' : basicHeader
    });
    return this.http.get(url, {headers: headers});
  }
  //Server returns a JSONARRAY respresenting the roles of the user.
  checkSession() {
    let url = this.serverPath+'/checkSession';
    let headers = new Headers({
        'x-auth-token' : localStorage.getItem('xAuthToken')
    });
    return this.http.get(url, {headers: headers});
  }
  logout() {
    let url = this.serverPath+'/user/logout';
    let headers = new Headers({
        'x-auth-token' : localStorage.getItem('xAuthToken')
    });
    return this.http.post(url, '', {headers: headers});
  }
}

【讨论】:

  • 您的代码看起来不错。您可以为这两种服务创建单独的文件,这样您在继续使用它们时就不会感到困惑。
猜你喜欢
  • 2015-07-02
  • 2018-03-14
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 2016-02-05
  • 2018-06-27
相关资源
最近更新 更多