当前位置: 首页 > 知识库问答 >
问题:

Gmail Api Request的身份验证范围不足

洪逸清
2023-03-14

我正在尝试使用Gmail API阅读电子邮件,但我面临权限不足的问题。

注意:我已将范围设置为阅读电子邮件。

ManiFestFile。xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hatsoff.glogin">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.GLogin">
    <activity
        android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

我创建了GoogleSignInOptions来动态获取emailAddress或User。

  //assign googleAuth
    googleAuth = new GoogleAuth();
    // request for google email
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
            .requestIdToken(getString(R.string.server_client_id))
            .requestServerAuthCode(getString(R.string.server_client_id))
            .requestEmail()
            .build();
    // google_signing object to store gso.
    mGoogleSignInClient = GoogleSignIn.getClient(getApplicationContext(), gso);

当用户从GSOGogleSigninoOptions对话框中选择GoogleAccount时,调用了someActivityResultLauncher。

        //google Dialog click event
    someActivityResultLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if (result.getResultCode() == RESULT_OK) {
                        System.out.println("ActivityResult: " + result.getResultCode());
                        Intent data = result.getData();
                        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
                        authCode = googleAuth.handleSignInResult(task);
                        if (authCode != null) {
                            // Signed in successfully
                            // save AuthCode to sharedPref
                        }
                    } else {
                        System.out.println("ActivityResult: " + result.getResultCode());
                    }
                }
            });

要获取AccessToken,我正在使用GoogleTokenResponse。

ReadEmail类

    public class ReadMails extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... strings) {
        SharedPreferences AuthCodePre = getSharedPreferences("oAuth", MODE_PRIVATE);
        if (!AuthCodePre.getString("Auth", "").equals("")) {
            try {
                String MailBody = "";
                // Load client secrets.
                AssetManager am = getAssets();
                InputStream in = am.open("credentials.json");
                if (in == null) {
                    throw new FileNotFoundException("Resource not found: " + in);
                }
                GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
                final NetHttpTransport HTTP_TRANSPORT = new com.google.api.client.http.javanet.NetHttpTransport();
                GoogleTokenResponse tokenResponse =
                        new GoogleAuthorizationCodeTokenRequest(
                                HTTP_TRANSPORT,
                                JSON_FACTORY,
                                "https://oauth2.googleapis.com/token",
                                clientSecrets.getDetails().getClientId(),
                                clientSecrets.getDetails().getClientSecret(),
                                AuthCodePre.getString("Auth", ""),
                                "http://localhost")
                                .setScopes(Arrays.asList(SCOPES))
                                .execute();

                String accessToken = tokenResponse.getAccessToken();
                // Use access token to call API
                Credential credential = new GoogleCredential.Builder().setTransport(new com.google.api.client.http.javanet.NetHttpTransport())
                        .setJsonFactory(JSON_FACTORY)
                        .setClientSecrets(clientSecrets.getDetails().getClientId(), clientSecrets.getDetails().getClientSecret())
                        .build()
                        .setAccessToken(accessToken);

                // Build a new authorized API client service.
                Gmail service = new Gmail.Builder(new NetHttpTransport(), JacksonFactory.getDefaultInstance(), credential)
                        .setApplicationName(APPLICATION_NAME)
                        .build();
                //Access gmail inbox
                Gmail.Users.Messages.List RequestList = service.users().messages().list(user).setQ("from:abcd@gmail.com");
                ListMessagesResponse listMessagesResponse = RequestList.setMaxResults(100L).execute();
                RequestList.setPageToken(listMessagesResponse.getNextPageToken());

                //Get id of search email
                for (int i = 0; i < listMessagesResponse.getMessages().size(); i++) {
                    String SEmailID = listMessagesResponse.getMessages().get(i).getId();
                    com.google.api.services.gmail.model.Message message = service.users().messages().get(user, SEmailID).execute();
                    //read email body
                    MessagePart msgpart = message.getPayload();
                    List<MessagePart> bodyParts = new ArrayList<>();
                    bodyParts.add(msgpart);
                    for (int j = 0; j < bodyParts.size(); j++) {
                        MailBody = StringUtils.newStringUtf8(Base64.decodeBase64(bodyParts.get(j).getBody().getData()));
                    }
                    System.out.println("EmailBody:==> " + MailBody);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //signIn
            someActivityResultLauncher.launch(mGoogleSignInClient.getSignInIntent());
        }
        return null;
    }
}

GoogleAuth。Java语言

    public class GoogleAuth {
    public String handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);
            System.out.println("ServerAuthCode: " + account.getServerAuthCode());
            return account.getServerAuthCode();
        } catch (ApiException e) {
            System.out.println("getStatusCode: " + e);
            return null;
        }
    }
}

错误日志

W/System.err: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Insufficient Permission",
 W/System.err:     "reason" : "insufficientPermissions"
  } ],
  "message" : "Request had insufficient authentication scopes.",
  "status" : "PERMISSION_DENIED"
}

此行出错:ListMessagesResponse ListMessagesResponse=RequestList。setMaxResults(100L)。执行();

共有1个答案

年凯康
2023-03-14

您已授权您的申请

Scope(Scopes.DRIVE_APPFOLDER)

使用者消息列表需要以下作用域之一

将范围更改为适当的范围并让您的用户重新授权您的应用程序。当用户运行应用程序时,同意屏幕需要显示新范围。

 类似资料:
  • 我第一次尝试使用Google Firestore,通过Google api身份验证进行身份验证。我要做的第一件事是用几个方法来填充数据库,当我等待批处理任务时,会出现以下错误: 我几乎找不到谷歌认证连接firestore的方法。首先,我使用google console为我的应用程序提供的密码使用此方法进行身份验证: 使用在我的google控制台中为应用程序配置的相同作用域(我在同一应用程序中使用g

  • null 所用程序: 获取身份验证响应后创建Google analytics service对象。/li> 脚本: null

  • 我是新来的,我不是程序员,那我需要你的帮助。 我正在测试说明管理老师和学生在这里找到:https://developers.google.com/classroom/guides/manage-users 我尝试使用身份验证和作用域,就像在PHP QuickStart中一样:https://developers.google.com/classroom/quickstart/php 我成功运行了q

  • 这是我为Google Sheets API编写的代码。我有这是我找到的解决此问题的方法,但这并不能解决我的问题。我已经删除了我的.Credentials文件夹,它不提示我登录。

  • 我正在尝试使用iOS版的Google Sheets API获取Google Sheet。我已经成功添加了用户身份验证,因为它不再要求API密钥,但我现在收到403错误,原因是: 我在Google Developers Console中添加了以下范围。 下面是我用来生成和执行查询的代码。 是否有办法使用Google Sheets API for iOS指定查询范围?我很好地浏览了这个框架,它似乎从来