0

我正在使用 Spring Boot 开发一个 Angular 应用程序。我开发了一个以用户名密码作为输入的登录页面。从后端对用户进行身份验证并发送成功和失败响应的 Web 服务。以及成功认证后显示的主页。

发生的事情是我也可以直接打开主页 URL 而无需登录,这不是正确的。

我需要的是实现一种机制来检查用户是否登录,并在此基础上显示 URL 页面或登录页面。

4

2 回答 2

2

在 Web 应用程序中处理身份验证的最佳实践之一是使用JWT在服务器端 生成和检查Token,并在前端和后端的通信中传递令牌。当您实现此功能并在服务器中进行身份验证后,您必须将Token存储在LocalStorageSessionStoragecockies中以供将来交互。

要在 Angular 应用程序中创建受保护的路由,您必须实现这些:

  • AuthService,它是一个 GET API,用于检查当前令牌与后端的验证。
  • AuthGuard可以使用路由上的AuthServiceCanActivate属性保护您想要的路由。

这是给您的示例代码:

应用程序-AuthGuard.ts

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

import { AuthenticationService } from '@app/_services';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
    constructor(
        private router: Router,
        private authenticationService: AuthenticationService
    ) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const currentUser = this.authenticationService.currentUserValue;
        if (currentUser) {
            // check if route is restricted by role
            if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
                // role not authorised so redirect to home page
                this.router.navigate(['/']);
                return false;
            }

            // authorised 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;
    }
}

auth.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { environment } from '@environments/environment';
import { User } from '@app/_models';

@Injectable({ providedIn: 'root' })
export class UserService {
    constructor(private http: HttpClient) { }

    getAll() {
        return this.http.get<User[]>(`${environment.apiUrl}/users`);
    }

    getById(id: number) {
        return this.http.get<User>(`${environment.apiUrl}/users/${id}`);
    }
}

app.routing.module.ts

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

import { HomeComponent } from './home';
import { AdminComponent } from './admin';
import { LoginComponent } from './login';
import { AuthGuard } from './_helpers';
import { Role } from './_models';

const routes: Routes = [
    {
        path: '',
        component: HomeComponent,
        canActivate: [AuthGuard]
    },
    {
        path: 'admin',
        component: AdminComponent,
        canActivate: [AuthGuard],
        data: { roles: [Role.Admin] }
    },
    {
        path: 'login',
        component: LoginComponent
    },

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

export const appRoutingModule = RouterModule.forRoot(routes);

有关更多信息和完整示例,请阅读本文: Angular 8 - 基于角色的授权教程与示例

于 2020-09-24T18:52:44.733 回答
0

听起来您需要在canActivate路由中添加路由保护。我会详细解释,但这篇文章可能会做得更好: http: //gnomeontherun.com/2017/03/02/guards-and-login-redirects-in-angular/

它的工作本质上是检查用户是否已登录,如果没有则重定向。还有一些其他细微差别的东西,例如在导航到/从站点(通常通过本地存储)时持续登录,但这应该可以为您提供所需的内容。

于 2020-09-24T18:31:45.040 回答