programing

로그인 페이지로 각도 리다이렉트

codeshow 2023. 3. 13. 20:42
반응형

로그인 페이지로 각도 리다이렉트

난 아스프에서 왔어사용자가 허가되지 않은 페이지에 접속하려고 하는 Net MVC 월드는 자동으로 로그인 페이지로 리다이렉트 됩니다.

이 동작을 Angular에 재현하려고 합니다.@CanActivate 데코레이터를 사용했는데 컴포넌트가 렌더링되지 않고 리다이렉트되지 않습니다.

질문은 다음과 같습니다.

  • Angular가 이 동작을 수행할 수 있는 방법을 제공합니까?
  • 만약 그렇다면, 어떻게?좋은 연습인가요?
  • 그렇지 않은 경우 Angular에서 사용자 인증을 처리하기 위한 베스트 프랙티스는 무엇입니까?

다음은 Angular 4(Angular 5 - 8과도 호환됨)를 사용한 업데이트된 예입니다.

AuthGuard에 의해 보호되는 홈루트가 있는 루트

import { Routes, RouterModule } from '@angular/router';

import { LoginComponent } from './login/index';
import { HomeComponent } from './home/index';
import { AuthGuard } from './_guards/index';

const appRoutes: Routes = [
    { path: 'login', component: LoginComponent },

    // home route protected by auth guard
    { path: '', component: HomeComponent, canActivate: [AuthGuard] },

    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

export const routing = RouterModule.forRoot(appRoutes);

사용자가 로그인하지 않은 경우 AuthGuard가 로그인 페이지로 리다이렉트합니다.

쿼리 매개 변수의 원래 URL을 로그인 페이지에 전달하도록 업데이트됨

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

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private router: Router) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        if (localStorage.getItem('currentUser')) {
            // logged in so return true
            return true;
        }

        // not logged in so redirect to login page with the return url
        this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
        return false;
    }
}

전체 예시와 작업 데모는 이 게시물을 참조하십시오.

업데이트: Github에서 OAuth2 통합이 가능한 풀 스켈레톤 Angular 2 프로젝트를 발표하였습니다.이 프로젝트에서는 아래 지시사항이 실제로 수행되고 있습니다.

중 하나는 I/O를 입니다.directive 2와 Angular 2는 달니다.componentsAttributive Directive는 기본적으로 사용자가 페이지에 삽입하는 새로운 HTML 태그(관련 코드 포함)로, 일부 동작을 유발하는 태그에 삽입하는 속성입니다.여기 의사들.

커스텀 어트리뷰트가 존재하면 디렉티브를 배치한 컴포넌트(또는 HTML 요소)에 문제가 발생합니다.현재 Angular2/OAuth2 응용 프로그램에 사용하는 다음 지침을 고려하십시오.

import {Directive, OnDestroy} from 'angular2/core';
import {AuthService} from '../services/auth.service';
import {ROUTER_DIRECTIVES, Router, Location} from "angular2/router";

@Directive({
    selector: '[protected]'
})
export class ProtectedDirective implements OnDestroy {
    private sub:any = null;

    constructor(private authService:AuthService, private router:Router, private location:Location) {
        if (!authService.isAuthenticated()) {
            this.location.replaceState('/'); // clears browser history so they can't navigate with back button
            this.router.navigate(['PublicPage']);
        }

        this.sub = this.authService.subscribe((val) => {
            if (!val.authenticated) {
                this.location.replaceState('/'); // clears browser history so they can't navigate with back button
                this.router.navigate(['LoggedoutPage']); // tells them they've been logged out (somehow)
            }
        });
    }

    ngOnDestroy() {
        if (this.sub != null) {
            this.sub.unsubscribe();
        }
    }
}

이렇게 하면 사용자가 이미 로그인했는지 여부를 판단하기 위해 작성한 인증 서비스를 사용하여 사용자가 로그아웃하거나 타임아웃 했을 때 사용자가 퇴출될 수 있도록 인증 이벤트에 가입합니다.

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★사용자가 인증되었음을 나타내는 필요한 쿠키 또는 기타 상태 정보가 있는지 확인하는 나와 같은 지시문을 작성합니다.찾고 있는 플래그가 없는 경우, 사용자를 메인 공개 페이지(저처럼) 또는 OAuth2 서버(또는 기타)로 리디렉션합니다.보호해야 하는 모든 컴포넌트에 이 디렉티브 속성을 붙입니다.때는 '아까', '아까', '아까', '아까', '아까'라고 부르기도 .protected위에 붙여놓은 지시문처럼요

<members-only-info [protected]></members-only-info>

그런 다음 앱 내에서 사용자를 로그인 보기로 이동/재연결하고 인증 작업을 수행할 수 있습니다.현재 경로를 원하는 경로로 변경해야 합니다.따라서 이 경우 종속성 주입을 사용하여 Router 개체를 디렉티브에서 가져옵니다.constructor() 후 ''을 합니다.navigate()사용자를 로그인 페이지로 송신하는 방법(위의 예와 같습니다).

은, 「」, 「」를 로 하고 .<router-outlet>을 사용하다

@RouteConfig([
    {path: '/loggedout', name: 'LoggedoutPage', component: LoggedoutPageComponent, useAsDefault: true},
    {path: '/public', name: 'PublicPage', component: PublicPageComponent},
    {path: '/protected', name: 'ProtectedPage', component: ProtectedPageComponent}
])

대신에, OAuth2 서버등의 외부 URL 에 유저를 리다이렉트 할 필요가 있는 경우는, 다음과 같은 조작을 지시합니다.

window.location.href="https://myserver.com/oauth2/authorize?redirect_uri=http://myAppServer.com/myAngular2App/callback&response_type=code&client_id=clientId&scope=my_scope

최종 라우터에서의 사용

새로운 라우터가 도입됨에 따라 루트의 보호가 쉬워졌습니다.서비스로서 기능하는 가드를 정의하고 루트에 추가해야 합니다.

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { UserService } from '../../auth';

@Injectable()
export class LoggedInGuard implements CanActivate {
  constructor(user: UserService) {
    this._user = user;
  }

  canActivate() {
    return this._user.isLoggedIn();
  }
}

이번에는 ㅇㅇ, .LoggedInGuard.providers모듈 어레이

import { LoginComponent } from './components/login.component';
import { HomeComponent } from './components/home.component';
import { LoggedInGuard } from './guards/loggedin.guard';

const routes = [
    { path: '', component: HomeComponent, canActivate: [LoggedInGuard] },
    { path: 'login', component: LoginComponent },
];

모듈 선언:

@NgModule({
  declarations: [AppComponent, HomeComponent, LoginComponent]
  imports: [HttpModule, BrowserModule, RouterModule.forRoot(routes)],
  providers: [UserService, LoggedInGuard],
  bootstrap: [AppComponent]
})
class AppModule {}

최종 릴리즈에서의 동작에 대한 자세한 블로그 투고:https://medium.com/@blacksonic86/black-2-authentication-incertiated-3bf9

사용되지 않는 라우터에서의 사용

은 '보다 낫다'를 입니다.RouterOutlet및 루트를 액티브하게 할 때는, 유저가 로그인하고 있는지를 확인합니다.이렇게 하면 지시문을 복사하여 모든 구성요소에 붙여넣을 필요가 없습니다. 서브 하는 것은 를 일으킬 이 있습니다.

@Directive({
  selector: 'router-outlet'
})
export class LoggedInRouterOutlet extends RouterOutlet {
  publicRoutes: Array;
  private parentRouter: Router;
  private userService: UserService;

  constructor(
    _elementRef: ElementRef, _loader: DynamicComponentLoader,
    _parentRouter: Router, @Attribute('name') nameAttr: string,
    userService: UserService
  ) {
    super(_elementRef, _loader, _parentRouter, nameAttr);

    this.parentRouter = _parentRouter;
    this.userService = userService;
    this.publicRoutes = [
      '', 'login', 'signup'
    ];
  }

  activate(instruction: ComponentInstruction) {
    if (this._canActivate(instruction.urlPath)) {
      return super.activate(instruction);
    }

    this.parentRouter.navigate(['Login']);
  }

  _canActivate(url) {
    return this.publicRoutes.indexOf(url) !== -1 || this.userService.isLoggedIn()
  }
}

UserService는 사용자의 로그인 여부에 관계없이 비즈니스 로직이 상주하는 위치를 나타냅니다.컨스트럭터에 DI를 사용하면 쉽게 추가할 수 있습니다.

사용자가 웹 사이트의 새 URL로 이동하면 현재 지침에서 활성화 메서드가 호출됩니다.여기서 URL을 가져와 허용 여부를 결정할 수 있습니다.로그인 페이지로 리다이렉트 하는 것만이 아닙니다.

마지막으로 남은 것은 빌트인 컴포넌트가 아닌 메인 컴포넌트로 전달하는 것입니다.

@Component({
  selector: 'app',
  directives: [LoggedInRouterOutlet],
  template: template
})
@RouteConfig(...)
export class AppComponent { }

하실 수 .@CanActive decorator:이false가 : Lifecycle decorator.RouterOutlet호출되지 않습니다.

상세한 블로그 투고도 작성했습니다.https://medium.com/@blacksonic86/authentication-in-timeout-2-958052c64492

라우터 아웃렛을 덮어쓰지 마십시오!최신 라우터 릴리즈(3.0 베타판)에서는 악몽입니다.

대신 CanActivate 및 CanDeactivate 인터페이스를 사용하여 루트 정의에서 클래스를 canActivate / canDeactivate로 설정합니다.

이런 식으로:

{ path: '', component: Component, canActivate: [AuthGuard] },

클래스:

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(protected router: Router, protected authService: AuthService)
    {

    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {

        if (state.url !== '/login' && !this.authService.isAuthenticated()) {
            this.router.navigate(['/login']);
            return false;
        }

        return true;
    }
}

참고 항목: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard

위의 멋진 답변에 따라 저도 하고 싶습니다.CanActivateChild: 자경로를 지킨다.추가에 사용할 수 있습니다.guardACL과 같은 경우에 도움이 되는 루트를 자녀에게 전달합니다.

그건 이런 식이다.

src/app/auth-guard.service.ts(해당)

import { Injectable }       from '@angular/core';
import {
  CanActivate, Router,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  CanActivateChild
}                           from '@angular/router';
import { AuthService }      from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
  constructor(private authService: AuthService, private router:     Router) {}

  canActivate(route: ActivatedRouteSnapshot, state:    RouterStateSnapshot): boolean {
    let url: string = state.url;
    return this.checkLogin(url);
  }

  canActivateChild(route: ActivatedRouteSnapshot, state:  RouterStateSnapshot): boolean {
    return this.canActivate(route, state);
  }

/* . . . */
}

src / app / admin / admin - http . ts ( )pt) sr )

const adminRoutes: Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [AuthGuard],
    children: [
      {
        path: '',
        canActivateChild: [AuthGuard],
        children: [
          { path: 'crises', component: ManageCrisesComponent },
          { path: 'heroes', component: ManageHeroesComponent },
          { path: '', component: AdminDashboardComponent }
        ]
      }
    ]
  }
];

@NgModule({
  imports: [
    RouterModule.forChild(adminRoutes)
  ],
  exports: [
    RouterModule
  ]
})
export class AdminRoutingModule {}

이것은 https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard 에서 가져온 것입니다.

이 코드 auth.ts 파일을 참조해 주세요.

import { CanActivate } from '@angular/router';
import { Injectable } from '@angular/core';
import {  } from 'angular-2-local-storage';
import { Router } from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {
constructor(public localStorageService:LocalStorageService, private router: Router){}
canActivate() {
// Imaginary method that is supposed to validate an auth token
// and return a boolean
var logInStatus         =   this.localStorageService.get('logInStatus');
if(logInStatus == 1){
    console.log('****** log in status 1*****')
    return true;
}else{
    console.log('****** log in status not 1 *****')
    this.router.navigate(['/']);
    return false;
}


}

}
// *****And the app.routes.ts file is as follow ******//
      import {  Routes  } from '@angular/router';
      import {  HomePageComponent   } from './home-page/home- page.component';
      import {  WatchComponent  } from './watch/watch.component';
      import {  TeachersPageComponent   } from './teachers-page/teachers-page.component';
      import {  UserDashboardComponent  } from './user-dashboard/user- dashboard.component';
      import {  FormOneComponent    } from './form-one/form-one.component';
      import {  FormTwoComponent    } from './form-two/form-two.component';
      import {  AuthGuard   } from './authguard';
      import {  LoginDetailsComponent } from './login-details/login-details.component';
      import {  TransactionResolver } from './trans.resolver'
      export const routes:Routes    =   [
    { path:'',              component:HomePageComponent                                                 },
    { path:'watch',         component:WatchComponent                                                },
    { path:'teachers',      component:TeachersPageComponent                                         },
    { path:'dashboard',     component:UserDashboardComponent,       canActivate: [AuthGuard],   resolve: { dashboardData:TransactionResolver } },
    { path:'formone',       component:FormOneComponent,                 canActivate: [AuthGuard],   resolve: { dashboardData:TransactionResolver } },
    { path:'formtwo',       component:FormTwoComponent,                 canActivate: [AuthGuard],   resolve: { dashboardData:TransactionResolver } },
    { path:'login-details', component:LoginDetailsComponent,            canActivate: [AuthGuard]    },

]; 

1. Create a guard as seen below. 2. Install ngx-cookie-service to get cookies returned by external SSO. 3. Create ssoPath in environment.ts (SSO Login redirection). 4. Get the state.url and use encodeURIComponent.

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from 
  '@angular/router';
import { CookieService } from 'ngx-cookie-service';
import { environment } from '../../../environments/environment.prod';

@Injectable()
export class AuthGuardService implements CanActivate {
  private returnUrl: string;
  constructor(private _router: Router, private cookie: CookieService) {}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    if (this.cookie.get('MasterSignOn')) {
      return true;
    } else {
      let uri = window.location.origin + '/#' + state.url;
      this.returnUrl = encodeURIComponent(uri);      
      window.location.href = environment.ssoPath +  this.returnUrl ;   
      return false;      
    }
  }
}

언급URL : https://stackoverflow.com/questions/34331478/angular-redirect-to-login-page

반응형