You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Guards如何实现禁止手动访问URL同时允许页面刷新

解决方案

核心思路是借助sessionStorage区分「正常路由跳转/刷新」和「手动输入URL访问」两种场景,不需要拆分Guard,同一个Guard即可同时实现两个需求。

实现逻辑

  • 正常通过站内路由跳转进入受保护页面时,router.navigated值为true,直接放行,同时写入权限标记到sessionStorage
  • 页面刷新时,router.navigated初始值为false,但sessionStorage中的权限标记仍然存在,判断到标记存在即可放行
  • 手动输入URL访问受保护页面时,sessionStorage中没有权限标记,且router.navigated为false,直接重定向到首页
  • sessionStorage会在当前标签页关闭后自动清空,不会遗留无效权限,也不会跨标签页互相干扰

完整代码

import { Injectable } from '@angular/core';
import { CanActivate, Router, NavigationStart, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class NavigationGuard implements CanActivate {
  private readonly PERMISSION_KEY = 'hasRoutePermission';

  constructor(private router: Router) {
    // 监听路由跳转事件,跳转到非受保护公共页时清除权限标记
    this.router.events.subscribe(event => {
      if (event instanceof NavigationStart) {
        // 可根据实际业务调整需要清除标记的路由范围
        if (event.url === '/' || event.url === '/login') {
          sessionStorage.removeItem(this.PERMISSION_KEY);
        }
      }
    });
  }

  canActivate(): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    // 正常路由跳转未刷新的场景
    if (this.router.navigated) {
      sessionStorage.setItem(this.PERMISSION_KEY, 'true');
      return true;
    }

    // 页面刷新的场景
    if (sessionStorage.getItem(this.PERMISSION_KEY) === 'true') {
      return true;
    }

    // 手动输入URL访问的场景,重定向到首页
    this.router.navigate(['/']);
    return false;
  }
}

注意事项

  • 退出登录逻辑中需要主动调用sessionStorage.removeItem('hasRoutePermission')清除权限标记,避免退出后刷新页面仍可访问受保护页
  • 可根据业务需求调整清除权限标记的路由规则,比如所有公共页跳转都清除标记,进一步提升安全性

内容的提问来源于stack exchange,提问作者PepeW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 23:36:04