简体   繁体   English

Gmail 发送请求导致“身份验证范围不足”错误

[英]Gmail Send request results in "insufficient authentication scopes" error

I try to send mail use Gmail API .我尝试使用Gmail API发送邮件。 My code almost the same like in google tutorial, but when I invoice this send Message method I get error Request had insufficient authentication scopes .我的代码与谷歌教程中的代码几乎相同,但是当我为这个发送消息方法开票时,我收到错误Request had insufficient authentication scopes

This is full stacktrace of error:这是错误的完整堆栈跟踪:

POST https://gmail.googleapis.com/gmail/v1/users/example.com@gmail.com/messages/send
{
  "code": 403,
  "details": [
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT"
    }
  ],
  "errors": [
    {
      "domain": "global",
      "message": "Insufficient Permission",
      "reason": "insufficientPermissions"
    }
  ],
  "message": "Request had insufficient authentication scopes.",
  "status": "PERMISSION_DENIED"
}
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
POST https://gmail.googleapis.com/gmail/v1/users/example.com@gmail.com/messages/send
{
  "code": 403,
  "details": [
    {
      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
      "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT"
    }
  ],
  "errors": [
    {
      "domain": "global",
      "message": "Insufficient Permission",
      "reason": "insufficientPermissions"
    }
  ],
  "message": "Request had insufficient authentication scopes.",
  "status": "PERMISSION_DENIED"
}

This is my code:这是我的代码:

public class GmailService {
    /**
     * Application name.
     */
    private static final String APPLICATION_NAME = "example.com";
    private static final String EXAMPLE_EMAIL = "example.com@gmail.com";
    /**
     * Global instance of the JSON factory.
     */
    private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
    /**
     * Directory to store authorization tokens for this application.
     */
    private static final String TOKENS_DIRECTORY_PATH = "tokens";

    /**
     * Global instance of the scopes required by this quickstart.
     * If modifying these scopes, delete your previously saved tokens/ folder.
     */
    private static final List<String> SCOPES = new ArrayList<>();
    private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

    /**
     * Creates an authorized Credential object.
     *
     * @param HTTP_TRANSPORT The network HTTP Transport.
     * @return An authorized Credential object.
     * @throws IOException If the credentials.json file cannot be found.
     */
    private Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
        SCOPES.add(GmailScopes.GMAIL_LABELS);
        SCOPES.add(GmailScopes.GMAIL_SEND);
        SCOPES.add(GmailScopes.MAIL_GOOGLE_COM);
        // Load client secrets.
        InputStream in = GmailService.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        if (in == null) {
            throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
        }
        final GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

        // Build flow and trigger user authorization request.
        final GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
                .setAccessType("offline")
                .build();
        LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
        Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
        //returns an authorized Credential object.
        return credential;
    }

    public boolean sendMessage(String recipientAddress, String subject, String body) throws MessagingException,
            IOException, GeneralSecurityException {

        Message message = createMessageWithEmail(
                createEmail(recipientAddress, EXAMPLE_EMAIL, subject, body));

        return createGmail().users()
                .messages()
                .send(EXAMPLE_EMAIL, message)
                .execute()
                .getLabelIds().contains("SENT");
    }

    private MimeMessage createEmail(String to, String from, String subject, String bodyText) throws MessagingException {
        MimeMessage email = new MimeMessage(Session.getDefaultInstance(new Properties(), null));
        email.setFrom(new InternetAddress(from));
        email.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(to));
        email.setSubject(subject);
        email.setText(bodyText);
        return email;
    }

    private Message createMessageWithEmail(MimeMessage emailContent) throws MessagingException, IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        emailContent.writeTo(buffer);

        return new Message()
                .setRaw(Base64.encodeBase64URLSafeString(buffer.toByteArray()));
    }

    private Gmail createGmail() throws IOException, GeneralSecurityException {

        // Build a new authorized API client service.
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        return new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                .setApplicationName(APPLICATION_NAME)
                .build();
    }
}

What I neet to do?我需要做什么?

I use OAuth 2.0 Client IDs credential:我使用 OAuth 2.0 客户端 ID 凭据:

{
  "web": {
    "client_id": "[REDACTED].googleusercontent.com",
    "project_id": "example-3523409",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "[REDACTED]",
    "redirect_uris": [
      "http://localhost:8888/Callback",
    ],
    "javascript_origins": [
      "http://localhost:4200",
      "http://localhost:8888",
      "http://localhost:8080"
    ]
  }
}

It looks like your post is mostly code;看起来您的帖子主要是代码; please add some more details.请添加更多细节。

The Gmail.send method requires that the user authencation the application with one of the following scopes in order to run Gmail.send方法要求用户使用以下范围之一验证应用程序才能运行

在此处输入图像描述

The error message Request had insufficient authentication scopes.错误消息Request had insufficient authentication scopes. means that the currently authencation user has not authorized the application with one of those scopes.表示当前身份验证用户尚未使用这些范围之一授权应用程序。

In your code i can see that you have added在您的代码中,我可以看到您已添加

SCOPES.add(GmailScopes.GMAIL_LABELS);
SCOPES.add(GmailScopes.GMAIL_SEND);
SCOPES.add(GmailScopes.MAIL_GOOGLE_COM);

the Gmail_send scope should be enough. Gmail_send scope 应该足够了。

However your code is storing user tokens in TOKENS_DIRECTORY_PATH.但是,您的代码将用户令牌存储在 TOKENS_DIRECTORY_PATH 中。 Which makes me thing that you previously authorized this user with a reduced scope.这让我觉得你以前用减少的 scope 授权了这个用户。 Then you added the new scopes ran your application again.然后,您添加了新范围,再次运行您的应用程序。 However with the authorization tokens being stored in TOKENS_DIRECTORY_PATH your application is still picking up the old user consent and the old scopes.但是,由于授权令牌存储在 TOKENS_DIRECTORY_PATH 中,您的应用程序仍在获取旧用户同意和旧范围。

Solution is to delete what ever is in TOKENS_DIRECTORY_PATH and run your application again the consent screen should pop up and request authorization of the user again.解决方案是删除 TOKENS_DIRECTORY_PATH 中的内容并再次运行您的应用程序,同意屏幕应弹出并再次请求用户授权。 This time including the proper scopes.这次包括适当的范围。

Note web app:注意 web 应用程序:

You appear to be using web app credentials yet the code you are using is for AuthorizationCodeInstalledApp.您似乎正在使用 web 应用程序凭据,但您使用的代码用于 AuthorizationCodeInstalledApp。 This code may not work if you try hosting it on a web server.如果您尝试将其托管在 web 服务器上,此代码可能不起作用。

Unless you are using JavaScript you don't need to set the javascript_origins in your credentials.除非您使用的是 JavaScript,否则您不需要在凭据中设置 javascript_origins。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过 Google Classroom API 创建教师时请求的身份验证范围不足错误 - Request had insufficient authentication scopes error when creating teacher through Google Classroom API 谷歌表 API(带有 java)显示“消息”:“请求的身份验证范围不足。”,“状态”:“PERMISSION_DENIED” - Google sheet API (with java) is showing “message” : “Request had insufficient authentication scopes.”, “status” : “PERMISSION_DENIED” GoogleJsonResponseException:403认证范围不足而被禁止 - GoogleJsonResponseException: 403 Forbidden with insufficient authentication scopes Gmail-API JAVA客户端发送电子邮件权限不足 - Gmail-API JAVA Client Send Email Insufficient Permission 向Google发送身份验证请求 - Send an authentication request to Google 在Java中发送不带gmail身份验证的电子邮件 - send email w/o gmail authentication in java 为什么GMail接受未经身份验证的邮件发送? - Why GMail is accepting to send mail without Authentication? 我无法通过使用Gmail身份验证的JavaMail API在Android中发送电子邮件,未检测到错误 - i could not send e-mail in Android using the JavaMail API using Gmail authentication no error detected 如何更改Spring&Jhipster身份验证不足的错误消息 - How to change Spring & Jhipster Insufficient authentication error message 使用gmail smtp服务器和javamail在Java中发送未经身份验证的电子邮件 - Send Email Without authentication in java using gmail smtp server and javamail
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM