我正在尝试从 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] 删除。
我来说两句