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

Android使用Retrofit实现GitHub Basic Auth获取仓库及双因素认证集成问题

问题原因
  • 授权头格式错误:调用getUser接口时你使用Credentials.basic(username, password)生成了符合规范的Basic xxx格式授权头,但在fetchRepos方法中直接传入纯PAT字符串作为授权头,不符合GitHub API的认证要求,会导致权限校验失败。
  • 接口选择错误:当前使用的GET users/{user}/repos接口仅能获取指定用户的公开仓库列表,即使认证成功也无法返回私有仓库。要获取当前授权用户的全部公开+私有仓库,需要使用GET /user/repos接口,该接口会根据授权信息自动返回对应账号的所有可见仓库。
  • 可选问题:如果你的PAT未勾选repo相关权限,即使认证流程正确也无法读取私有仓库内容。
修复方案

首先调整GithubService接口定义:

public interface GithubService {
    @GET("user")
    Call<User> getUser(@Header("Authorization") String authHeader);

    // 替换原有userRepos接口,不需要传userId,直接获取当前授权用户的所有仓库
    @GET("user/repos")
    Call<List<GitHubRepo>> listCurrentUserRepos(@Header("Authorization") String authHeader);
}

调整fetchRepos方法逻辑,注意Retrofit实例建议抽成单例复用,不要每次请求都新建:

// 调用时额外传入用户名参数即可
private void fetchRepos(String username, String pat) {
    // 两种授权头格式二选一即可
    // 格式1:沿用Basic认证
    String cred = Credentials.basic(username, pat);
    // 格式2:PAT专属的Bearer认证
    // String cred = "Bearer " + pat;
    
    // 复用之前创建的GithubService实例发起请求
    service.listCurrentUserRepos(cred).enqueue(new Callback<List<GitHubRepo>>() {
        @Override
        public void onResponse(Call<List<GitHubRepo>> call, Response<List<GitHubRepo>> response) {
            Log.d(TAG, "请求结果:" + response.isSuccessful());
            if (response.isSuccessful()) {
                List<GitHubRepo> repos = response.body();
                // 处理返回的仓库列表
            } else {
                Log.d(TAG, "错误码:" + response.code() + " 错误信息:" + response.errorBody().string());
            }
        }

        @Override
        public void onFailure(Call<List<GitHubRepo>> call, Throwable t) {
            Log.d(TAG, "请求失败:" + t.getMessage());
        }
    });
}
双因素认证(2FA)集成方案

如果使用PAT认证不需要处理2FA,PAT本身已经是授权后凭证,会自动跳过2FA校验。只有使用用户名+密码的常规Basic认证时需要处理2FA流程:

  1. 第一次请求返回401状态码时,检查响应头是否存在X-GitHub-OTP字段,存在则说明需要2FA校验
  2. 弹出验证码输入框,引导用户输入收到的2FA验证码
  3. 重新发起请求时,除Authorization头外额外添加X-GitHub-OTP请求头,值为用户输入的验证码即可完成认证

对应调整后的接口示例:

@GET("user")
Call<User> getUser(@Header("Authorization") String authHeader, @Header("X-GitHub-OTP") String otpCode);

未开启2FA的用户调用时otpCode参数传null即可,Retrofit会自动忽略该请求头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:15:07