Xamarin Forms Google登录后Azure Functions验证Token报400错误
我帮你梳理下当前的问题和解决步骤,这应该能快速帮你搞定这个400错误:
1. 先修正最直接的请求参数错误
你现在犯了一个关键的参数名错误:把Google返回的id_token放到了请求体的client_id字段里,这完全不符合Azure Functions登录端点的要求。
Azure的/.auth/login/google端点(使用ID令牌流时),正确的请求体需要包含两个核心字段:
id_token: 你从Xamarin.Auth获取到的Google ID令牌内容client_id: Azure Functions配置的Google Web应用凭据的客户端ID(注意是Web应用的,不是Android应用的那个)
错误的请求体示例:
{"client_id": "eyJhbGciOiJSUzI1NiIsImtpZCI6..."}
正确的请求体示例:
{"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...", "client_id": "your-google-web-app-client-id.apps.googleusercontent.com"}
2. 解决令牌受众不匹配的隐藏问题
你提到Google API里有两个凭据(Android和Web应用),这里还有一个容易踩坑的点:
从Xamarin Android登录拿到的id_token,它的aud(受众)字段是Android应用的client_id,但Azure Functions默认只会验证aud等于自己配置的Web应用client_id的令牌,这也会导致「Invalid Client Credentials」错误。
这里有两个可行的解决方案:
方案A:让Android应用使用Web应用凭据登录
在Google Cloud Console中找到你的Web应用凭据,添加Android应用的包名和SHA-1指纹(和你创建Android凭据时的信息完全一致)。这样Xamarin Android就可以用Web应用的client_id登录,获取到的id_token的aud就是Web应用的client_id,Azure就能正常验证了。
修改Xamarin.Auth的登录代码,把ClientId换成Web应用的ID:
var authenticator = new OAuth2Authenticator( clientId: "your-google-web-app-client-id.apps.googleusercontent.com", scope: "openid email profile", authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/v2/auth"), redirectUrl: new Uri("com.yourcompany.yourapp:/oauth2redirect/google"));
方案B:调整Azure的认证规则
如果你不想修改Xamarin端的登录配置,可以在Azure Portal里调整认证的高级设置:
- 进入Azure Functions的「认证」面板,找到Google提供商
- 点击「编辑」,展开「高级设置」
- 勾选「允许令牌受众与客户端ID不匹配」
- 保存后,Azure就会接受
aud为Android应用client_id的令牌了
3. 修正后的Xamarin请求代码示例
var idToken = "从Xamarin.Auth获取的id_token"; var googleWebClientId = "Azure配置的Google Web应用client_id"; var requestBody = new { id_token = idToken, client_id = googleWebClientId }; var jsonContent = JsonConvert.SerializeObject(requestBody); var content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); var client = new HttpClient(); var response = await client.PostAsync("https://mysite.azurewebsites.net/.auth/login/google", content); if (response.IsSuccessStatusCode) { var authResult = await response.Content.ReadAsStringAsync(); // 处理返回的Azure认证令牌,比如提取access_token用于后续调用Functions } else { var error = await response.Content.ReadAsStringAsync(); Debug.WriteLine($"认证失败: {error}"); }
内容的提问来源于stack exchange,提问作者Mark Reimer

