GoogleSignIn对接Google API遇401未授权错误,求Android解决方案
我来帮你搞定这个Android端Google Sign-In对接Calendar API的401坑——之前做项目的时候我也碰到过一模一样的问题,大概率是权限配置或者令牌获取的环节没做对。iOS端能直接跑是因为框架默认帮你处理了权限关联,但Android端需要更明确的配置,咱们一步步来排查:
1. 补全GoogleSignInOptions的权限范围
你原来的代码只用到了DEFAULT_SIGN_IN,这个只能获取基础的用户身份信息,完全没有Calendar API的访问权限,这是最常见的问题。必须在构建GoogleSignInOptions时明确添加Calendar的权限scope:
// 导入必要的类 import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAuthUtil; import com.google.api.services.calendar.CalendarScopes; // 构建正确的GoogleSignInOptions GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() // 获取邮箱信息(可选,但建议加上) .requestScopes(new Scope(CalendarScopes.CALENDAR_READONLY)) // 关键:添加日历只读权限,需要读写就用CALENDAR .requestIdToken(getString(R.string.default_web_client_id)) // 调用REST API必须要这个,从Cloud Console获取 .build();
解释一下:DEFAULT_SIGN_IN只是让用户登录,不会请求第三方API的权限,所以必须手动添加CalendarScopes对应的权限,否则API调用肯定会返回401。
2. 获取带权限的访问令牌,而非默认ID Token
登录成功后,你不能直接用GoogleSignInAccount里的信息去调用API,必须通过GoogleAuthUtil获取专门的Access Token——ID Token是用来验证用户身份的,不是用来调用API的凭证。
示例代码:
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this); if (account != null) { // 必须在子线程中获取令牌,不能在主线程 new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { // 这里要和之前配置的scope保持一致 String scope = "oauth2:" + CalendarScopes.CALENDAR_READONLY; String accessToken = GoogleAuthUtil.getToken( getApplicationContext(), account.getAccount(), scope ); return accessToken; } catch (Exception e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(String accessToken) { if (accessToken != null) { // 用这个accessToken去调用Calendar API callCalendarApi(accessToken); } } }.execute(); }
3. 检查Google Cloud Console的配置
这一步很容易被忽略,也是导致401的常见原因:
- 确保你的Android客户端SHA-1指纹已经添加到OAuth 2.0客户端ID的配置里(在Cloud Console的API和服务→凭据里)
- 确保Calendar API已经在Cloud Console中启用(搜索“Calendar API”,点击启用按钮)
- 检查OAuth同意屏幕的配置:如果是测试阶段,要把测试用户添加进去;同时确认Calendar的权限已经列在“已授权的范围”里
4. 调试验证令牌权限
如果还是有问题,可以把获取到的Access Token拿到Google官方的OAuth令牌调试工具里验证,看看令牌的权限范围是否包含Calendar相关的scope。如果没有,那肯定是前面的scope配置环节出了问题,回去检查GoogleSignInOptions的构建代码。
按照这几步排查下来,基本就能解决Android端的401未授权问题了——核心就是要明确请求Calendar的权限,并且获取正确的API访问令牌,而不是只做基础的用户登录。
内容的提问来源于stack exchange,提问作者evenro

