使用 JWT 授权 GMail API

菲尔

我正在尝试从 Node.js 应用程序通过 gmail API 发送电子邮件。我按照文档并使用 node-mailer 包进行了这项工作。但是,我注意到当我们更改组织密码时,连接不再良好(这是有道理的)。因此,我尝试使用 JWT 进行授权。

JWT 已正确生成并发布到https://oauth2.googleapis.com/token. 此请求然后返回一个 access_token。

当需要编写和发送电子邮件时,我尝试简单地修改以前工作的代码(当时使用 client_secret、client_id 和 redirect_uris):

const gmail = google.gmail({ version: 'v1', auth: access_token });
  gmail.users.messages.send(
    {
      userId: 'email',
      resource: {
        raw: encodedMessage
      }
    },
    (err, result) => {
      if (err) {
        return console.log('NODEMAILER - The API returned: ' + err);
      }

      console.log(
        'NODEMAILER  Sending email reply from server: ' + result.data
      );
    }
  );

API 不断返回Error: Login Required

有谁知道如何解决这个问题?

编辑

我修改了我的代码和身份验证以添加 client_id 和 client_secret:

const oAuth2Client = new google.auth.OAuth2(
      credentials.gmail.client_id,
      credentials.gmail.client_secret,
      credentials.gmail.redirect_uris[0]
    );

    oAuth2Client.credentials = {
      access_token: access_token
    };
    const gmail = google.gmail({ version: 'v1', auth: oAuth2Client });
    gmail.users.messages.send(
      {
        userId: 'email',
        resource: {
          raw: encodedMessage
        }
      },
      (err, result) => {
        if (err) {
          return console.log('NODEMAILER - The API returned: ' + err);
        }

        console.log(
          'NODEMAILER  Sending email reply from server: ' + result.data
        );
      }
    );

但现在错误更不精确: Error: Bad Request

菲尔

这是对我有用的最终授权代码:

var credentials = require('../../credentials');
    const privKey = credentials.gmail.priv_key.private_key;

    var jwtParams = {
      iss: credentials.gmail.priv_key.client_email,
      scope: 'https://www.googleapis.com/auth/gmail.send',
      aud: 'https://oauth2.googleapis.com/token',
      exp: Math.floor(new Date().getTime() / 1000 + 120),
      iat: Math.floor(new Date().getTime() / 1000),
      sub: [INSERT EMAIL THAT WILL BE SENDING (not the service email, the one that has granted delegated access to the service account)]
    };

    var gmail_token = jwt.sign(jwtParams, privKey, {
      algorithm: 'RS256'
    });

    var params = {
      grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
      assertion: gmail_token
    };

    var params_string = querystring.stringify(params);

    axios({
      method: 'post',
      url: 'https://oauth2.googleapis.com/token',
      data: params_string,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }).then(response => {
      let mail = new mailComposer({
        to: [ARRAY OF RECIPIENTS],
        text: [MESSAGE CONTENT],
        subject: subject,
        textEncoding: 'base64'
      });

      mail.compile().build((err, msg) => {
        if (err) {
          return console.log('Error compiling mail: ' + err);
        }

        const encodedMessage = Buffer.from(msg)
          .toString('base64')
          .replace(/\+/g, '-')
          .replace(/\//g, '_')
          .replace(/=+$/, '');

        sendMail(encodedMessage, response.data.access_token, credentials);
      });
    });

所以上面的代码段使用私钥创建了一个 JSON Web Token (JWT),其中:iss 是要使用的服务帐户,scope 是被访问的 gmail API 的端点(必须预先授权),aud 是google API oAuth2 端点,exp 是过期时间,iat 是创建时间,sub 是服务帐户所代理的电子邮件。

然后对令牌进行签名并向 Google oAuth2 端点发出 POST 请求。成功后,我使用 NodeMailer 的 mailComposer 组件构建电子邮件,其中包含一组收件人、一条消息、一个主题和一个编码。然后对该消息进行编码。

这是我的sendMail()功能:

const oAuth2Client = new google.auth.OAuth2(
      credentials.gmail.client_id,
      credentials.gmail.client_secret,
      credentials.gmail.redirect_uris[0]
    );

    oAuth2Client.credentials = {
      access_token: access_token
    };

    const gmail = google.gmail({ version: 'v1', auth: oAuth2Client });
    gmail.users.messages.send(
      {
        userId: 'me',
        resource: {
          raw: encodedMessage
        }
      },
      (err, result) => {
        if (err) {
          return console.log('NODEMAILER - The API returned: ' + err);
        }

        console.log(
          'NODEMAILER  Sending email reply from server: ' + result.data
        );
      }
    );

在此函数中,我使用服务帐户的凭据创建一个新的 googleapis OAuth2 对象(此处存储在外部文件中以增加安全性)。然后我传入 access_token(在使用 JWT 的身份验证脚本中生成)。然后发送消息。

要注意userId: 'me'sendMail()功能,这对我来说是至关重要的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何设置使用Javascript通过Gmail Api发送邮件的授权?

如何使用基于JWT令牌的授权保护fastapi API端点?

在 .NET Core 中使用 JWT 令牌或 API 密钥的授权机制

客户端未经授权使用此方法检索访问令牌Gmail API C#

PHP Slim 4-使用Firebase JWT令牌授权api请求

在ASP.NET Core Web Api中使用JWT授权检查IP

使用 fetch API 授权

使用 JWT 令牌授权仍然返回未授权

使用JWT缺少授权标头

使用 Axios 发布请求的 JWT 授权

使用不带身份的Bearer / Jwt授权

使用JWT受众字段来授权角色

.NET 5.0使用JWT和OpenId授权

如何使用JWT令牌授权Swagger jsdoc?

在 Node 中使用 JWT 进行授权

访问未授权或过期 GMAIL API 和 Oauth2 / 如何使用 GMAIL API 和 GSuite 域设置电子邮件签名

Gmail API-无法使用google.auth.jwt从域中的用户获取邮件

授权错误,错误400:Gmail API redirect_uri_mismatch

使用AWS API Gateway时是否可以从自定义Lambda授权器传回JWT有效负载?

正确的方法来设置IdentityServer4 Cookies进行登录,使用JWT令牌进行API授权

未经授权使用 API 密钥

从哪里获得授权的Gmail API服务实例?(Python,Gmail API)

HTTP API网关JWT授权者从cookie获取身份源

通过 JWT 令牌在 Azure API 管理中授权

基于JWT的API + Piranha CMS HiJacks [授权]路由

带有JWT的Core 2.0 API Auth返回未授权

JWT始终在.net Core API上返回未经授权的401

调试AWS HTTP API(beta)JWT授权方

需要连接iTunes Connect API,总是显示未授权JWT