Flutter登录后调用Azure API遇重定向,无法获取预期JSON响应
问题:调用Azure API时收到登录页面重定向,无法获取JSON响应
问题背景
在Flutter应用中使用aad_oauth包调用Azure API,已成功登录并获取Microsoft访问令牌,但调用携带Bearer令牌的GET API时,返回登录页面HTML而非预期的JSON响应。
现有配置与代码
aad_oauth配置
static final Config config = Config( tenant: '***', clientId: '***', scope: 'openid profile offline_access', navigatorKey: Get.key, redirectUri: '***', loader: SizedBox()); static final AadOAuth oauth = AadOAuth(config);
登录代码(LoginViewModel.dart)
final result = await oAuth.login(); String accessToken = await oAuth.getAccessToken();
已确认访问令牌正确获取并存储。
API调用代码(使用dio)
@override Future<ShipGroupModel?> getShips() async { try { final Response<dynamic> response = await _dio.get( "/api/ship", ); } on DioError catch (e) { // 异常处理 } }
错误现象
API返回200状态码,但响应体为登录页面HTML:
<!-- Copyright (C) Microsoft Corporation. All rights reserved. --> <!DOCTYPE html> <html dir="ltr" class="" lang="en"> <head> <title>Sign in to your account</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes"> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Expires" content="-1"> <link rel="preconnect" href="https://aadcdn.msauth.net" crossorigin> <meta http-equiv="x-dns-prefetch-control" content="on"> <link rel="dns-prefetch" href="//aadcdn.msauth.net"> <link rel="dns-prefetch" href="//aadcdn.msftauth.net"> <meta name="PageID" content="ConvergedSignIn" /> <meta name="SiteID" content="" /> <meta name="ReqLC" content="1033" /> <meta name="LocLC" content="en-US" /> <meta name="referrer" content="origin" /> <meta name="format-detection" content="telephone=no" /> <noscript> <meta http-equiv="Refresh" content="0; URL=https://login.microsoftonline.com/jsdisabled" /> </noscript> <meta name="robots" content="none" /> <script type="text/javascript">//<... JS code here ...></script> </body> </html>
响应中包含重定向URL:
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?client_id={client_id}&redirect_uri={redirect_uri}&client_info={client_info}
解决方法
1. 为请求添加Authorization头
当前dio请求未携带Bearer令牌,这是核心问题。修改API调用代码,在请求头中加入获取到的accessToken:
@override Future<ShipGroupModel?> getShips() async { try { final Response<dynamic> response = await _dio.get( "/api/ship", options: Options( headers: { 'Authorization': 'Bearer $accessToken', // 替换为你的accessToken变量 }, ), ); return ShipGroupModel.fromJson(response.data); } on DioError catch (e) { // 异常处理 print(e.response?.data); return null; } }
2. 更新aad_oauth的scope配置
当前scope仅包含基础身份权限,缺少目标Azure API的访问权限。需添加API的scope,格式通常为api://{api-client-id}/.default或具体权限(如api://xxx/Ships.Read):
scope: 'openid profile offline_access api://{your-api-client-id}/.default',
替换{your-api-client-id}为你的Azure API客户端ID。
3. 验证令牌有效性
解析accessToken,确认:
aud(受众)字段匹配目标API的客户端IDscp或roles字段包含所需的API权限
4. 检查API身份验证配置
确保Azure API的应用注册中,已将Flutter应用的客户端ID加入允许列表,且API权限已完成管理员同意。
内容的提问来源于stack exchange,提问作者peppe
相关产品推荐
相关产品推荐

