You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在PHP中使用IMAP与OAuth 2.0从Gmail读取邮件(替换密码为刷新令牌)

嘿,针对你的两个PHP Gmail IMAP OAuth2问题,我来一步步帮你解决:


1. 在PHP中使用IMAP与OAuth 2.0从Gmail获取邮件

首先得做好前置准备工作:

  • 登录Google Cloud Console,创建一个新项目
  • 启用Gmail API(在API库中搜索并启用)
  • 创建OAuth 2.0客户端ID:选择对应的应用类型(比如桌面应用或Web应用),设置授权回调URL(Web应用必填,桌面应用可以用http://localhost
  • 记录下你的客户端ID客户端密钥

接下来是代码实现,推荐使用Google官方的google/apiclient包来简化OAuth流程,先安装依赖:

composer require google/apiclient:^2.0

步骤1:获取用户授权码并换取令牌

这段代码会引导用户授权,获取授权码后交换为访问令牌和刷新令牌(如果是离线授权的话):

require __DIR__ . '/vendor/autoload.php';

$client = new Google\Client();
$client->setClientId('YOUR_CLIENT_ID');
$client->setClientSecret('YOUR_CLIENT_SECRET');
$client->setRedirectUri('YOUR_REDIRECT_URI');
// 权限根据需求调整,只读用gmail.readonly,全访问用mail.google.com
$client->addScope('https://mail.google.com/');
// 开启离线访问,这样才能获取刷新令牌
$client->setAccessType('offline');
$client->setPrompt('select_account consent');

if (!isset($_GET['code'])) {
    // 生成授权URL并跳转
    $authUrl = $client->createAuthUrl();
    header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
} else {
    // 用授权码换取令牌
    $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
    $client->setAccessToken($token);
    
    // 把$token(包含refresh_token)存储到安全的地方,比如数据库
    file_put_contents('token.json', json_encode($token));
    
    echo "授权成功,令牌已保存!";
}

步骤2:使用访问令牌连接IMAP并获取邮件

有了访问令牌后,就可以连接Gmail的IMAP服务器了:

require __DIR__ . '/vendor/autoload.php';

$client = new Google\Client();
$client->setClientId('YOUR_CLIENT_ID');
$client->setClientSecret('YOUR_CLIENT_SECRET');
// 从存储中读取令牌
$token = json_decode(file_get_contents('token.json'), true);
$client->setAccessToken($token);

// 如果访问令牌过期,自动用刷新令牌更新(google/apiclient会自动处理)
if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    file_put_contents('token.json', json_encode($client->getAccessToken()));
}

// IMAP连接字符串
$imapHost = '{imap.gmail.com:993/imap/ssl/authuser=YOUR_GMAIL_ADDRESS@gmail.com/oauth2}INBOX';
// 连接IMAP,密码填访问令牌
$imapStream = imap_open($imapHost, 'YOUR_GMAIL_ADDRESS@gmail.com', $client->getAccessToken()['access_token']);

if (!$imapStream) {
    die('IMAP连接失败: ' . imap_last_error());
}

// 获取最新的10封邮件
$emails = imap_search($imapStream, 'ALL', SE_UID);
if ($emails) {
    rsort($emails); // 按最新到最旧排序
    foreach (array_slice($emails, 0, 10) as $emailUid) {
        $header = imap_headerinfo($imapStream, $emailUid);
        echo "主题: " . $header->subject . "<br>";
        echo "发件人: " . $header->fromaddress . "<br><br>";
    }
}

// 关闭连接
imap_close($imapStream);

2. 替换为OAuth 2.0刷新令牌的实现方式

你现在用的基于用户密码的方式可以完全替换为刷新令牌流程,核心是不再依赖用户密码,而是用刷新令牌自动获取新的访问令牌,不用每次让用户重新授权。下面是关键实现步骤:

核心逻辑

刷新令牌的作用是在访问令牌过期时,直接通过它获取新的访问令牌,无需用户再次授权。关键要点:

  • 第一次授权时必须开启offline访问类型($client->setAccessType('offline');),Google才会返回刷新令牌
  • 刷新令牌要安全存储(比如后端数据库加密存储,绝对不能暴露给前端)

手动用刷新令牌获取新访问令牌(不依赖官方库)

如果你不想用google/apiclient,可以手动发送请求获取:

$clientId = 'YOUR_CLIENT_ID';
$clientSecret = 'YOUR_CLIENT_SECRET';
$refreshToken = 'YOUR_STORED_REFRESH_TOKEN';

$tokenUrl = 'https://oauth2.googleapis.com/token';
$postData = [
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'refresh_token' => $refreshToken,
    'grant_type' => 'refresh_token'
];

$ch = curl_init($tokenUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

$response = curl_exec($ch);
curl_close($ch);

$tokenData = json_decode($response, true);

if (isset($tokenData['access_token'])) {
    $newAccessToken = $tokenData['access_token'];
    // 存储新的访问令牌(如果返回新的refresh_token也要更新)
    echo "新的访问令牌: " . $newAccessToken;
} else {
    die('刷新令牌失效: ' . $tokenData['error_description']);
}

用新访问令牌连接IMAP

和之前的连接逻辑一致,把密码替换为新的访问令牌即可:

$imapHost = '{imap.gmail.com:993/imap/ssl/authuser=YOUR_GMAIL_ADDRESS@gmail.com/oauth2}INBOX';
$imapStream = imap_open($imapHost, 'YOUR_GMAIL_ADDRESS@gmail.com', $newAccessToken);

// 后续邮件操作和之前一致...

注意事项

  • 确保Gmail账户已开启IMAP功能:在Gmail设置->转发和POP/IMAP中启用IMAP
  • 权限范围:如果只需要读取邮件,用https://www.googleapis.com/auth/gmail.readonly即可,权限越小越安全
  • 刷新令牌有效期:Web应用的刷新令牌如果6个月未使用或用户撤销授权会失效;桌面应用的刷新令牌长期有效
  • 令牌存储:一定要加密存储刷新令牌,避免泄露

内容的提问来源于stack exchange,提问作者laurel

火山引擎 最新活动