当前位置: 首页 > 知识库问答 >
问题:

如何通过Gmail SMTP安全发送电子邮件

居焱
2023-03-14

以下代码https://stackoverflow.com/a/3649148一直有效,直到最近谷歌改变了他们的安全政策,它才被打破。

我收到了来自谷歌的邮件

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

我们强烈建议您使用Gmail等安全应用程序访问您的帐户。Google制作的所有应用程序都符合这些安全标准。另一方面,使用不太html" target="_blank">安全的应用程序可能会使您的帐户易受攻击。了解更多。

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

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

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

共有2个答案

郑茂材
2023-03-14

您需要使用OAUTH发送电子邮件。展望未来,每个谷歌应用程序都将使用oauth。

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

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

荀嘉熙
2023-03-14

我必须在一个基于PHP的网页上实现这一点,因为我们的服务器没有邮件服务器,而我们使用的是谷歌的邮件服务器。谷歌很可能会在未来切断对其服务的任何未经授权的访问;我们希望有一个经得起未来考验的解决方案。我认为将此解决方案移植到其他语言(如标记的Java)应该不是什么大问题。

启用云控制台的Google mail帐户、启用https的web域、PHP 5.4或更高版本以及JSON扩展(从v5.2开始捆绑,但有时无论如何都没有安装-我们假定它已经安装)和大量耐心。

此外,我们需要PHP Google API Client库,可以使用以下方式获得:

  • 服务器的命令行界面(CLI)和Composer依赖管理器。优点是您会自动接收更新。Google API库很大,有办法排除不需要的部分。

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

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

创建新项目后,转到库部分,找到Gmail API并启用它。

您显然需要一些鉴别数据。启用API应该会将您重定向到Gmail API控制台界面-在左侧菜单中选择凭据:

创建新的OAuth客户端ID

  • 但您被告知首先在OAuth许可屏幕上指定产品标题-选择create new OAuth client ID将在左侧菜单中显示许可屏幕选项卡

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

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

  • 单击“添加范围”

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

  • 添加授权域-这些将被允许访问api(没有协议,只有顶级:gmapi.xy
  • 添加应用程序主页、隐私政策和服务条款链接-与上述相同(但完整地址:https://gmapi.xyORhttps://gmapi.xy/policyetc.)

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

保存更改:保存表单。我们已经要求了额外的范围-我们可能会看到一个警告:

此应用程序未经验证。

如果用户正在请求提供敏感用户数据访问权限的作用域,则显示给用户的OAuth同意屏幕可能会显示警告“此应用未验证”。这些应用程序最终必须经过验证过程,以消除该警告和其他限制。在开发阶段,您可以单击“高级”继续跳过此警告

一旦您的应用程序运行、活跃、公开且未处于开发阶段,请提交应用程序进行验证(保存旁边的按钮)。新应用程序的验证可能需要数周时间。

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

  • 选择Web应用程序作为类型
  • 使用您的URI填充授权的javascript源,在我的例子中https://gmapi.xyhttps://www.gmapi.xy
  • 填充授权重定向URI-google会向用户询问权限,您必须指定google API允许重定向回的URI。在我的例子中,我使用的是重定向到自身的test.php(具有https://www.gmapi.xy/test.phpURI)。因此,我将在那里添加https://www.gmapi.xy/test.phphttps://gmapi.xy/test.php

允许的重定向URL有很多问题,您不能以签名结尾。如果您的真实URI没有,如果您使用的不是默认的端口号,则必须指定端口号。。。有关更多信息,请参阅此线程。有一份清单供您使用:

  • 超文本传输协议还是https?

注意:拥有多个允许的URI可能会损害您的脚本-在成功授权后,您仍然可以在重定向回您的网页后收到此错误。

  • 保存表单(您不必复制成功创建OAuth ID时提供的凭据-关闭弹出窗口)
  • 下载JSON凭据文件-在OAuth 2.0客户端ID部分,单击箭头图标
  • 通过Composer安装google API库:作曲家需要google/apiclient:^2.0
  • 可选:运行Google_Task_Composer::cleanup任务并指定要保留在composer.json中的服务:
    {
        "require": {
            "google/apiclient": "^2.7"
        },
        "scripts": {
            "post-update-cmd": "Google_Task_Composer::cleanup"
        },
        "extra": {
            "google/apiclient-services": [
                "Drive",
                "YouTube"
            ]
        }
    }

注意:此方法似乎存在尚未解决的问题。因此,我没有尝试此功能。我也找不到可用的服务名称列表,因此如果有人找到它并添加链接会很好。

下载任意<代码>。zip-从所需PHP版本的发行版中获得的稳定版本,并将其放置在网站的某个位置(上载.zip并将其解压缩)。

还上载JSON凭据文件。

安全通知:将其放置在安全的地方:删除除所有者之外的任何人的R/W权限或使用. htaccess保护此文件!

然后只需包括自动加载。php(在服务器上找到库的路径,它应该位于供应商文件夹中),并提供身份验证凭据。

require_once '/path/to/google-api-php-client/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig('/path/to/client_credentials.json');

此外,您必须请求范围权限并从服务中获取令牌。可用的范围列表在此处可用。此外,有关范围的更多示例,请参阅此线程。

$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));
    }
}

首先,该网页将我们重定向到google,我们需要在其中授予我们的应用程序对所需电子邮件的访问权限以发送消息。一旦获得批准,就会创建一个令牌文件,我们将其存储在文件中。当令牌过期时,应该使用fetchAccessTokenSusReFresToken()自动创建一个新令牌-更多信息。

根据您想做的事情,您可能希望限制身份验证的能力。我们使用API来访问我们的系统电子邮件,不允许网站通过页面用户发送邮件,因此:

// 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'];
function createMessage($sender, $to, $subject, $messageText) {
    $message = new Google_Service_Gmail_Message();

    $rawMessageString = "From: <{$sender}>\r\n";
    $rawMessageString .= "To: <{$to}>\r\n";
    $rawMessageString .= 'Subject: =?utf-8?B?' . base64_encode($subject) . "?=\r\n";
    $rawMessageString .= "MIME-Version: 1.0\r\n";
    $rawMessageString .= "Content-Type: text/html; charset=utf-8\r\n";
    $rawMessageString .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
    $rawMessageString .= "{$messageText}\r\n";

    $rawMessage = strtr(base64_encode($rawMessageString), array('+' => '-', '/' => '_'));
    $message->setRaw($rawMessage);
    return $message;
}

function sendMessage($service, $userId, $message) {
    try {
        return $service->users_messages->send($userId, $message);
    } catch (Exception $e) {
        //todo error - use $e->getMessage();
    }
    return null;
}

sendMessage(new Google_Service_Gmail($client), 'me', createMessage(...));
  • https://github.com/googleapis/google-api-php-client
  • https://developers.google.com/gmail/api/quickstart/php
  • https://github.com/googleapis/google-api-php-client/blob/master/docs/oauth-server.md#creating-a-service-account
  • https://github.com/googleapis/google-api-php-client/blob/master/docs/oauth-web.md
  • https://blog.mailtrap.io/send-emails-with-gmail-api/
 类似资料:
  • 问题内容: 在我的中,我具有以下内容: 我的电子邮件代码: 当然,如果通过设置调试服务器,则可以在终端中看到该电子邮件。 但是,我实际上如何不将电子邮件发送到调试服务器,而是发送到user@gmail.com? 阅读你的答案后,让我弄明白一点: 你不能使用localhost(简单的ubuntu pc)发送电子邮件吗? 我认为在django 1.3中已经过时了,取而代之的是? 问题答案: 将电子邮件

  • 谷歌正在推动我们提高对他们的gmail smtp服务器的脚本访问的安全性。我对此没有意见。事实上我很乐意帮忙。

  • 问题内容: 我正在尝试使用 Go通过gmail API 发送电子邮件,但我发现文档存在缺陷/令人困惑。有一次我没有看到收据字段或电子邮件正文。 我不需要上传任何内容,因此我发现简单上传,分段上传,可恢复的上传方法完全没有用。是否有任何清晰的演示(带有所需的数据/参数,例如cURL有效负载)? 顺便提一句,我不确定是否我是唯一一个想到这一点的人,但是除非有可用的库,否则Google api似乎在可用

  • 我被困在一个公司防火墙后面,它不允许我通过Java Mail API或Apache Commons电子邮件等传统方式发送电子邮件,甚至不允许我发送给公司内部的其他人(无论如何,这就是我想要的)。但我的Outlook 2010显然可以发送这些电子邮件。我想知道是否有办法通过Java代码自动化Outlook 2010,以便Outlook可以发送电子邮件?我知道像“mailto”这样的东西可以用来弹出带

  • 问题内容: 我正在使用。 使用发送电子邮件(通过)的最佳方法是什么? 问题答案: 有关使用Outlook的解决方案,请参见下面的TheoretiCAL答案。 否则,请使用python随附的smtplib。请注意,这将要求您的电子邮件帐户允许smtp,默认情况下不一定启用此功能。 编辑: 此示例使用保留域,如RFC2606中所述 为了使它真正与gmail配合使用,Doe先生需要进入gmail中的选项

  • 我使用的PHPMailer表格在这里找到。 从网站下载的示例是“接触-3”,在引导主题中使用PHPMailer通过gmail发送SMTP电子邮件。当我使用“接触-1”时,它完全适用于我的托管域电子邮件地址,但SMTP版本适用于gmail地址,联系人表单不会提交。 在下面的代码中,我更改了以下行以添加我的gmail地址和gmail密码: 任何关于使用给定信息进行此工作的帮助都将不胜感激-提前感谢!