如何以安全的方式通过Gmail SMTP发送电子邮件

时间:2015-08-06 04:31:30

标签: java security email gmail

以下代码https://stackoverflow.com/a/3649148一直有效,直到Google最近更改了他们的安全政策时才破解。

我收到了来自Google的邮件

  

您好xxx,有人刚试图登录您的Google帐户   来自不符合现代安全标准的应用程序的xxx@gmail.com。

     

我们强烈建议您使用Gmail等安全应用进行访问   你的帐户。 Google生产的所有应用均符合这些安全标准。   另一方面,使用安全性较低的应用可能会离开您的帐户   脆弱。了解更多。

     

Google停止了此次登录尝试,但您应该检查一下   最近使用的设备:

我看https://support.google.com/accounts/answer/6010255?hl=en-GB

我想知道,实施正确的登录尝试的方法是什么,以便继续通过Gmail SMTP发送电子邮件,用户端配置为0?

2 个答案:

答案 0 :(得分:0)

您需要使用OATH发送电子邮件。展望未来,每个谷歌应用都将使用誓言。

快速而肮脏的修复将为不太安全的应用启用访问权限。 默认情况下,Google会锁定大多数第三方客户端的IMAP访问权限,但您可以在此处更改并继续发送电子邮件。

https://www.google.com/settings/security/lesssecureapps

答案 1 :(得分:0)

OAuth 2.0

我必须在基于PHP的网页上实现此功能,因为我们的服务器没有邮件服务器,而我们使用的是Google的服务器。 Google将来可能会削减对他们服务的任何未经授权的访问;我们希望有一个面向未来的解决方案。我相信将此解决方案移植到其他语言(例如带标签的Java)应该不是什么大问题。

要求:

已启用Cloud Console的Google邮件帐户 ,已启用https的网络域,具有JSON扩展名的PHP 5.4或更高版本(自v5.2起捆绑销售,但有时仍未安装-我们认为它已经存在已安装)和很多耐心。

另外,我们需要PHP Google API Client library,可以使用以下方法获得:

  • 服务器的命令行界面(CLI)和Composer dependency manager。优点是您将自动接收更新。 Google API库非常庞大,可以通过多种方式排除不需要的部分。

OR

  • 从其存储库手动复制该库。优点是您只需要访问Web托管云服务,这在无法使用Composer管理器的情况下很有用。

1)在Google控制台中进行项目

首先,您需要在google console中创建一个项目。 从Google的角度对您要与网页邮件发送应用程序关联的帐户执行此设置-是的,这将是一个应用程序。登录后:项目选择,选择并创建一个新项目(从现在起,我的名称为 Gmail API )。我还将使用一个名为 gmapi.xy 的(不存在的)网页。

console

一旦创建了一个新项目,请转到“库”部分,找到Gmail API并启用它。

2)凭据

您显然需要一些身份验证数据。启用API后,应将您重定向到Gmail API控制台界面-在左侧菜单中选择凭据

创建新的 OAuth客户端ID

  • 但是系统提示您首先在OAuth同意屏幕上指定您的产品标题-选择创建新的OAuth客户端ID 将在左侧菜单中显示“同意​​屏幕”标签。

2 a)创建产品(OAuth同意屏幕)

您需要填写名称,支持电子邮件,范围,授权域和OAuth限制

范围: 您需要指定授予将通过Gmail API进行身份验证的任何人的所有特权:

  • 点击“添加范围”
  • 在Gmail API部分中向下滚动并启用所有需要的范围(在我的情况下,我只想发送邮件,因此我也启用了https://www.googleapis.com/auth/gmail.send范围。

授权域: 填写您要从中发送电子邮件的域:

  • 添加授权域-这些域将被允许访问api(无协议,仅顶层:gmapi.xy
  • 添加应用首页,隐私权政策和服务链接条款-与我的情况相同(但完整地址:https://gmapi.xyhttps://gmapi.xy/policy等)

OAuth授权限制: 我对默认设置感到满意,因此无需更改(有关此主题的更多信息,请参见https://developers.google.com/analytics/devguides/config/mgmt/v3/limits-quotas

保存更改: 保存表格。我们要求其他范围-可能会看到警告:

此应用未通过验证。

显示给用户的OAuth同意屏幕可能会显示警告“此应用未验证”,如果该请求正在请求提供对敏感用户数据的访问权限的范围。这些应用程序最终必须经过验证过程才能删除该警告和其他限制。在开发阶段,您可以通过单击高级>转到{项目名称}(不安全)来继续克服此警告。

一旦您的应用运行,运行,公开并且处于开发阶段,请提交应用进行验证({{1}旁边的按钮)。您对新应用的验证最多可能需要几周

2 b)再次创建凭据

现在我们可以创建凭据了-和以前一样,在左侧菜单中选择凭据。创建新的 OAuth客户端ID

  • 选择 Web应用程序作为类型
  • 用您的URI(在我的情况下为Savehttps://gmapi.xy
  • 中填充授权的javascript来源
  • 填充授权的重定向URI -谷歌将询问用户特权,并且您必须指定允许Google API重定向回的URI。就我而言,我使用的是重定向到自身的https://www.gmapi.xy(具有test.php URI)。因此,我将在其中添加https://www.gmapi.xy/test.phphttps://www.gmapi.xy/test.php

允许的重定向URL有很多问题,如果您的真实URI没有一个,则不能以https://gmapi.xy/test.php结尾,如果您使用的是默认端口,则必须指定端口号。请参阅{{ 3}},以获取更多信息。 有一个清单供您使用:

  • http或https?
  • &或&?
  • 后跟斜杠(/)或打开?
  • (CMD / CTRL)+ F,在凭据页面中搜索完全匹配。如果找不到,则搜索丢失的那个。
  • 等待直到Google刷新它。如果您经常更改,则可能每半小时发生一次,或者可能停留在游泳池中。就我而言,生效将近半小时。
  • 更改OAuth ID中的值后,您是否重新导入了/文件?

注意:拥有多个允许的URI可能会损害您的脚本-成功获得授权后,重定向回到您的网页后,您仍然可以获得this thread。< / p>

  • 保存表单(成功创建OAuth ID后,您无需复制提供的凭据-关闭弹出窗口)
  • 下载credentials.json凭据文件-在 OAuth 2.0客户端ID 部分中,单击箭头图标

3 a)设置PHP-使用Composer

    通过Composer
  • 安装Google API库:JSON

  • (可选):运行composer require google/apiclient:^2.0任务并指定要保留在Google_Task_Composer::cleanup中的服务:

    { “要求”:{ “ google / apiclient”:“ ^ 2.7” }, “脚本”:{ “ post-update-cmd”:“ Google_Task_Composer :: cleanup” }, “额外”:{ “ google / apiclient-services”:[ “驾驶”, “ YouTube” ] } }

注意:这种方法似乎this error尚未解决。因此,我没有尝试此功能。我也找不到可用的服务名称列表,因此,如果有人找到它并添加了链接,那就太好了。

3 b)设置PHP-不带Composer

从所需的PHP版本issues下载任何composer.json-稳定版本,并将其放置在网站中的某个位置(上载.zip并将其解压缩)。

4包括库,您的凭据并准备进行身份验证

还上传.zip凭据文件。

安全通知:将其放置在安全的地方:删除所有者以外的任何人的读写权限,或使用JSON保护此文件!

然后仅包含.htaccess(在服务器上的库中找到其路径,它应该位于autoload.php文件夹中)并提供身份验证凭据。

vendor

此外,您必须请求范围特权并从服务中获取require_once '/path/to/google-api-php-client/vendor/autoload.php'; $client = new Google_Client(); $client->setAuthConfig('/path/to/client_credentials.json'); 。可用范围列表可用releases。另外,有关范围的更多示例,请参见here

token

首先,该网页将我们重定向到Google,我们需要在其中授予我们的应用程序访问所需电子邮件的权限,以便与之发送消息。一旦获得批准,便会创建一个令牌文件,并将其存储在文件中。当令牌过期时,应使用$client->setPrompt("consent"); $client->setScopes(array( 'https://www.googleapis.com/auth/gmail.send' //add more if you want to have them, or add // "https://mail.google.com/" to read, compose, send, delete mails )); $client->setAccessType('offline'); $client->setIncludeGrantedScopes(true); $tokenPath = 'where/you/want/to/store/token.json'; // Get new token - see redirect below if (isset($_GET['code'])) { $accessToken = $client->fetchAccessTokenWithAuthCode($_GET['code']); // Save the token to a file. if (!file_exists(dirname($tokenPath))) { mkdir(dirname($tokenPath), 0700, true); } file_put_contents($tokenPath, json_encode($accessToken)); $client->setAccessToken($accessToken); } else if (file_exists($tokenPath)) { // Get the saved token $accessToken = json_decode(file_get_contents($tokenPath), true); $client->setAccessToken($accessToken); } // If there is no previous token or it's expired. if ($client->isAccessTokenExpired()) { // Refresh the token if possible, else fetch a new one. $refreshToken = $client->getRefreshToken(); if ($refreshToken) { $client->fetchAccessTokenWithRefreshToken($refreshToken); } else { // Get the token - redirect to the same page $redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; $client->setRedirectUri($redirect_uri); $auth_url = $client->createAuthUrl(); // Actually GO to the authentication (and authorization) url header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } } -this thread自动创建一个新令牌。

但为了以防万一,我建议您这样做:

fetchAccessTokenWithRefreshToken()

5发送电子邮件!

// Get the token - redirect to the same page
if ( user_not_administrator ) {
    //TODO: redirect user to some error page and get yourself a notification
    exit;
}

$redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];

来源