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

Angular应用OAuth2授权跳转微软登录后提取access_token回跳原页咨询

解决方案

1. 前置路由配置

首先在Angular路由中新增一个授权回调路由,用来处理微软登录后的重定向请求:

// app-routing.module.ts
import { AuthCallbackComponent } from './auth-callback/auth-callback.component';

const routes: Routes = [
  // 原有路由,比如Authorize按钮所在的首页
  { path: '', component: HomeComponent },
  // 新增授权回调路由
  { path: 'auth-callback', component: AuthCallbackComponent },
  // 其他路由...
];

你需要提前在微软Azure的应用注册后台,把http://你的域名/auth-callback配置为合法的重定向地址。

2. 回调页实现令牌提取与存储

新建AuthCallbackComponent作为回调页的逻辑处理组件,该组件不需要额外的UI内容,只做参数提取、存储和跳转逻辑:

// auth-callback.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  template: '' // 空模板,用户看不到这个页面的内容
})
export class AuthCallbackComponent implements OnInit {
  constructor(private router: Router) {}

  ngOnInit(): void {
    // 处理hash片段中的参数(OAuth2隐式流默认参数存在#后)
    const hash = window.location.hash.substring(1); // 去掉开头的#
    const params = new URLSearchParams(hash);
    
    // 如果参数在query中就用下面这行替换上面两行
    // const params = new URLSearchParams(window.location.search);

    const accessToken = params.get('access_token');
    const expiresIn = params.get('expires_in');

    if (accessToken && expiresIn) {
      // 存储到sessionStorage
      sessionStorage.setItem('oauth_access_token', accessToken);
      // 计算绝对过期时间戳,方便后续判断是否过期
      const expireAt = Date.now() + parseInt(expiresIn) * 1000;
      sessionStorage.setItem('oauth_expire_at', expireAt.toString());

      // 跳转回授权按钮所在的首页
      this.router.navigate(['/']);
    } else {
      // 授权失败的处理逻辑,比如跳转到错误页
      this.router.navigate(['/'], { queryParams: { authError: 1 } });
    }
  }
}

3. 避免重复登录的逻辑处理

在原有「Authorize」按钮所在的组件初始化时,先判断sessionStorage中是否存在有效令牌,存在就直接跳过授权步骤:

// home.component.ts(授权按钮所在组件)
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html'
})
export class HomeComponent implements OnInit {
  isAuthenticated = false;

  ngOnInit(): void {
    const token = sessionStorage.getItem('oauth_access_token');
    const expireAt = sessionStorage.getItem('oauth_expire_at');
    
    // 判断令牌存在且未过期
    if (token && expireAt && Date.now() < parseInt(expireAt)) {
      this.isAuthenticated = true;
      // 这里可以直接执行已登录的后续逻辑,比如请求接口
    }
  }

  // 原有的授权按钮点击逻辑
  handleAuthorize(): void {
    if (this.isAuthenticated) return; // 已登录就不跳转
    // 你的微软OAuth2授权地址拼接逻辑
    const authUrl = '你的微软授权地址';
    window.location.href = authUrl;
  }
}

安全建议

  • 拼接授权地址时建议携带随机state参数,回调时验证state和本地存储的是否一致,避免CSRF攻击
  • 生产环境建议使用OAuth2授权码流替代隐式流,安全性更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:45:04