You need to enable JavaScript to run this app. Angular 11应用如何校验跨域调用方URL 实现指定来源访问控制
优惠活动
大模型
产品
解决方案
定价
更多

Angular 11应用如何校验跨域调用方URL 实现指定来源访问控制

核心问题根因

你之前尝试通过NavigationEnd拿不到来源地址是必然结果:这个事件是Angular Router专门用来追踪应用内部路由跳转的,只会记录本应用内不同路由节点之间的导航信息,从API设计层面就不会采集跨域外部站点跳转过来的入口来源,完全走不通这条路。
结合“不允许在URL上加参数做校验”的约束,下面是经过生产验证的可落地方案:

实现方案

主方案:浏览器原生document.referrer白名单校验

这是最适配当前约束的实现:

  • document.referrer是浏览器原生API,会自动记录当前页面上一个访问页面的完整URL,全程不需要在当前应用的URL上附加任何参数,完全合规
  • 校验逻辑要放在应用启动的最早节点(全局路由守卫、根组件初始化),避免非授权来源加载业务资源

示例代码(Angular 11 兼容写法):

// 全局来源校验守卫
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';

@Injectable({ providedIn: 'root' })
export class SourceCheckGuard implements CanActivate {
  // 预先配置允许访问的来源域名白名单
  private readonly ALLOWED_ORIGIN = new Set([
    'https://your-authorized-app-1.com',
    'https://your-authorized-app-2.com'
  ]);

  constructor(private router: Router) {}

  canActivate(): boolean {
    // 读取浏览器原生记录的跳转来源
    const referrerUrl = document.referrer;

    // 直接打开应用(书签、手动输URL等无来源场景)直接拦截
    if (!referrerUrl) {
      this.router.navigate(['/access-denied']);
      return false;
    }

    // 提取来源域名做白名单匹配
    const referrerOrigin = new URL(referrerUrl).origin;
    if (this.ALLOWED_ORIGIN.has(referrerOrigin)) {
      return true;
    }

    // 非授权来源跳转,拦截进无权限页
    this.router.navigate(['/access-denied']);
    return false;
  }
}

把这个守卫挂到根路由的所有受保护路径上,就能覆盖90%以上的常规跳转场景。

特殊场景补充

如果部分授权来源配置了referrerPolicy="no-referrer"导致document.referrer返回空值,依然不需要依赖URL参数:
当授权来源通过window.open新开窗口加载本应用时,本应用可以通过window.opener获取打开自身的父窗口对象,加载完成后主动用postMessage向父窗口发起身份校验请求,匹配白名单后再允许进入应用,整个交互过程完全不涉及URL参数透传。

落地注意点
  • 校验逻辑必须前置,不能等业务组件渲染完成再做判断,避免非授权来源提前拿到应用静态资源
  • 直接打开应用的场景(无referrer记录)直接拦截,完全匹配“禁止非授权来源直接打开”的需求
  • 前端校验属于第一道防线:由于document.referrer可被浏览器插件手动篡改,若安全等级要求较高,需要在后端接口层面做二次来源校验,避免前端校验被绕过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 19:27:04