2017-06-30 162 views
0

我正在开发一个快速的网页,当客户端点击“发送电子邮件”重定向到谷歌请求通过客户端电子邮件发送电子邮件的权限以及客户端把权限重定向回来并发送电子邮件。Gmail API发送电子邮件错误401:无效凭证

至今代码:

'use strict'; 

const express = require('express'); 
const googleAuth = require('google-auth-library'); 
const request = require('request'); 

let router = express.Router(); 
let app = express(); 

const SCOPES = [ 
    'https://mail.google.com/' 
    ,'https://www.googleapis.com/auth/gmail.modify' 
    ,'https://www.googleapis.com/auth/gmail.compose' 
    ,'https://www.googleapis.com/auth/gmail.send' 
]; 
const clientSecret = '***********'; 
const clientId = '**************'; 
const redirectUrl = 'http://localhost:8080/access-granted'; 
const auth = new googleAuth(); 
const oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl); 
const authUrl = oauth2Client.generateAuthUrl({ 
    access_type: 'offline', 
    scope: SCOPES 
}); 

function sendEmail(auth, content, to , from, subject) { 
    let encodedMail = new Buffer(
     `Content-Type: text/plain; charset="UTF-8"\n` + 
     `MIME-Version: 1.0\n` + 
     `Content-Transfer-Encoding: 7bit\n` + 
     `to: ${to}\n` + 
     `from: ${from}\n` + 
     `subject: ${subject}\n\n` + 

     content 
    ) 
    .toString(`base64`) 
    .replace(/\+/g, '-') 
    .replace(/\//g, '_'); 

    request({ 
     method: "POST", 
     uri: `https://www.googleapis.com/gmail/v1/users/me/messages/send`, 
     headers: { 
      "Authorization": `Bearer ${auth}`, 
      "Content-Type": "application/json" 
     }, 
     body: JSON.stringify({ 
      "raw": encodedMail 
     }) 
    }, 
    function(err, response, body) { 
     if(err){ 
      console.log(err); // Failure 
     } else { 
      console.log(body); // Success! 
     } 
    }); 

} 

app.use('/static', express.static('./www')); 
app.use(router) 

router.get('/access-granted', (req, res) => { 
    sendEmail(req.query.code, 'teste email', '[email protected]', '[email protected]', 'teste'); 
    res.sendfile('/www/html/index.html', {root: __dirname}) 
}) 

router.get('/request-access', (req, res) => { 
    res.redirect(authUrl); 
}); 

router.get('/', (req, res) => { 
    res.sendFile('/www/html/index.html', { root: __dirname }); 
}); 

const port = process.env.PORT || 8080; 
app.listen(port,() => { 
    console.log(`Server running at http://localhost:${port}`); 
}); 

module.exports = app; 

每次我试图发送一个简单的电子邮件我收到错误401:凭据无效。但我传递授权客户端代码验证,谷歌发送只给了我...

回答

1

推荐使用谷歌API的方式是使用Google API nodejs client,它也提供谷歌OAuth流。然后,您可以使用google.gmail('v1').users.messages.send发送电子邮件:

const gmail = google.gmail('v1'); 

gmail.users.messages.send({ 
    auth: oauth2Client, 
    userId: 'me', 
    resource: { 
     raw: encodedMail 
    } 
}, function(err, req) { 
    if (err) { 
     console.log(err); 
    } else { 
     console.log(req); 
    } 
}); 

authOAuth2,可与您的令牌填充的OAuth的对象。你可以在express session令牌:

var oauth2Client = getOAuthClient(); 
oauth2Client.setCredentials(req.session["tokens"]); 

,你已经保存在您的OAuth回调端点:

var oauth2Client = getOAuthClient(); 
var session = req.session; 
var code = req.query.code; 
oauth2Client.getToken(code, function(err, tokens) { 
    // Now tokens contains an access_token and an optional refresh_token. Save them. 
    if (!err) { 
     oauth2Client.setCredentials(tokens); 
     session["tokens"] = tokens; 
     res.send(`<html><body><h1>Login successfull</h1><a href=/send-mail>send mail</a></body></html>`); 
    } else { 
     res.send(`<html><body><h1>Login failed</h1></body></html>`); 
    } 
}); 

这里是this google API oauth for node.js example启发一个完整的例子:

'use strict'; 

const express = require('express'); 
const google = require('googleapis'); 
const request = require('request'); 
const OAuth2 = google.auth.OAuth2; 
const session = require('express-session'); 
const http = require('http'); 

let app = express(); 

app.use(session({ 
    secret: 'some-secret', 
    resave: true, 
    saveUninitialized: true 
})); 

const gmail = google.gmail('v1'); 

const SCOPES = [ 
    'https://mail.google.com/', 
    'https://www.googleapis.com/auth/gmail.modify', 
    'https://www.googleapis.com/auth/gmail.compose', 
    'https://www.googleapis.com/auth/gmail.send' 
]; 

const clientSecret = 'CLIENT_SECRET'; 
const clientId = 'CLIENT_ID'; 
const redirectUrl = 'http://localhost:8080/access-granted'; 

const mailContent = "test"; 
const mailFrom = "[email protected]"; 
const mailTo = "[email protected]"; 
const mailSubject = "subject"; 

function getOAuthClient() { 
    return new OAuth2(clientId, clientSecret, redirectUrl); 
} 

function getAuthUrl() { 
    let oauth2Client = getOAuthClient(); 

    let url = oauth2Client.generateAuthUrl({ 
     access_type: 'offline', 
     scope: SCOPES, 
     //use this below to force approval (will generate refresh_token) 
     //approval_prompt : 'force' 
    }); 
    return url; 
} 

function sendEmail(auth, content, to, from, subject, cb) { 
    let encodedMail = new Buffer(
      `Content-Type: text/plain; charset="UTF-8"\n` + 
      `MIME-Version: 1.0\n` + 
      `Content-Transfer-Encoding: 7bit\n` + 
      `to: ${to}\n` + 
      `from: ${from}\n` + 
      `subject: ${subject}\n\n` + 
      content 
     ) 
     .toString(`base64`) 
     .replace(/\+/g, '-') 
     .replace(/\//g, '_'); 

    gmail.users.messages.send({ 
     auth: auth, 
     userId: 'me', 
     resource: { 
      raw: encodedMail 
     } 
    }, cb); 
} 

app.use('/send-mail', (req, res) => { 
    let oauth2Client = getOAuthClient(); 
    oauth2Client.setCredentials(req.session["tokens"]); 
    sendEmail(oauth2Client, mailContent, mailTo, mailFrom, mailSubject, function(err, response) { 
     if (err) { 
      console.log(err); 
      res.send(`<html><body><h1>Error</h1><a href=/send-mail>send mail</a></body></html>`); 
     } else { 
      res.send(`<html><body><h1>Send mail successfull</h1><a href=/send-mail>send mail</a></body></html>`); 
     } 
    }); 
}); 

app.use('/access-granted', (req, res) => { 

    let oauth2Client = getOAuthClient(); 
    let session = req.session; 
    let code = req.query.code; 
    oauth2Client.getToken(code, function(err, tokens) { 
     // Now tokens contains an access_token and an optional refresh_token. Save them. 
     if (!err) { 
      oauth2Client.setCredentials(tokens); 
      session["tokens"] = tokens; 
      res.send(`<html><body><h1>Login successfull</h1><a href=/send-mail>send mail</a></body></html>`); 
     } else { 
      res.send(`<html><body><h1>Login failed</h1></body></html>`); 
     } 
    }); 
}) 

app.use('/', (req, res) => { 
    let url = getAuthUrl(); 
    res.send(`<html><body><h1>Authentication using google oAuth</h1><a href=${url}>Login</a></body></html>`) 
}); 

let port = process.env.PORT || 8080; 
let server = http.createServer(app); 
server.listen(port); 
server.on('listening', function() { 
    console.log(`listening to ${port}`); 
}); 
相关问题