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

Cypress测试请求成功仍弹出Azure Active Directory登录弹窗如何解决

核心问题

你当前的实现有三个致命问题,所以即使接口返回200,前端ADAL SDK依然判定未登录弹出弹窗:

  • 授权流选型错误:grant_type: "client_credentials"是服务间调用的无用户流,返回的token只代表应用身份,没有任何用户上下文,ADAL作为前端用户身份SDK,根本不认这类token。你之前直接把这个流返回的access_token塞到adal.idtoken字段里是无效的,这个字段要求的是带用户声明的id_token,client_credentials流根本不会返回id_token字段。
  • 存储写入上下文错误:你在cy.request回调里直接调用localStorage.setItem时,浏览器还没切到目标应用的域,写入的存储是存在Cypress测试运行器的默认域下,目标应用完全读不到这些值。
  • 缓存项缺失:你只存了不到一半ADAL校验登录态需要的缓存键,缺少用户信息、id_token过期标记、登录请求记录等必填项,ADAL初始化时扫不到完整的登录态标记,自然会触发登录流程。
修复步骤
  1. 替换授权流:把client_credentials流换成资源所有者密码流(ROPC),这个流可以直接通过账号密码拿到带用户上下文的id_token和access_token。注意要提前在Azure AD应用注册里开启「公共客户端流」选项,参数里传测试用户的账号密码,不是客户端密钥。
  2. 调整存储写入时机:先访问目标应用拿到对应域的window对象,再往这个window的localStorage/sessionStorage里写值,确保缓存能被应用读到。
  3. 补全所有必填缓存项:除了你已经写的几个键,还要补全id_token过期时间、用户信息、登录状态标记等ADAL强校验的字段。
  4. 写完缓存后重载页面,让ADAL初始化时直接读取缓存的登录态,不再跳登录。
修复后可运行代码
// 替换为实际测试账号信息,不要用客户端密钥
const testAccount = {
  username: 'test-user@your-tenant.onmicrosoft.com',
  password: 'test-user-password'
}
const clientId = 'myClientId';
const tenantId = 'myTenantId';
// 替换为你应用在Azure AD中配置的资源标识
const targetResource = clientId;

cy.request({
  method: "POST",
  url: `https://login.microsoftonline.com/${tenantId}/oauth2/token`,
  form: true,
  body: {
    grant_type: "password",
    client_id: clientId,
    username: testAccount.username,
    password: testAccount.password,
    resource: targetResource,
    scope: "openid profile"
  }
}).then((tokenRes) => {
  const { access_token: accessToken, id_token: idToken, expires_on: expiresOn } = tokenRes.body;
  // 解析id_token里的用户信息
  const userClaims = JSON.parse(atob(idToken.split('.')[1]));

  // 先进入目标应用,确保后续写入的存储在正确域名下
  cy.visit('myWebAppUrl');
  cy.window().then((win) => {
    const ls = win.localStorage;
    const ss = win.sessionStorage;
    // 原有缓存项
    ls.setItem("adal.token.keys", `${clientId}|`);
    ls.setItem(`adal.access.token.key${clientId}`, accessToken);
    ls.setItem(`adal.expiration.key${clientId}`, expiresOn);
    ls.setItem("adal.idtoken", idToken);
    // 补全缺失的必填缓存
    ls.setItem(`adal.idtoken.expiration.key${clientId}`, expiresOn);
    ls.setItem("adal.login.error", "");
    ls.setItem("adal.login.request", win.location.href);
    ls.setItem(`adal.user.name`, userClaims.upn);
    ls.setItem(`adal.user.profile`, JSON.stringify(userClaims));
    ss.setItem('access_token', accessToken);
  })
  // 重载页面让ADAL读取缓存登录态
  cy.reload();
})
注意事项

如果你的Azure AD租户开启了多因素认证(MFA),ROPC流会直接失效,这种场景建议直接用官方维护的ADAL/MSAL Cypress插件处理登录,不要手写请求。
如果你用的是MSAL v2而不是旧版ADAL,缓存键前缀会从adal.变为msal.,需要对应调整写入的键名,否则SDK读不到缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:03:27