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
相关产品推荐
相关产品推荐

