React结合Gmail API获取只读邮件遇403:权限配置与代码求助
解决Gmail API 403禁止访问问题(React + @react-oauth/google)
一、Google Cloud控制台权限配置
要访问Gmail API,必须先在Google Cloud控制台完成以下配置:
- 启用Gmail API:进入Google Cloud控制台,搜索「Gmail API」,点击启用按钮。
- 配置OAuth同意屏幕:
- 进入「OAuth同意屏幕」页面,选择外部类型(测试阶段)。
- 填写应用名称、支持邮箱等基础信息后,进入「范围」配置环节。
- 添加以下权限范围:
https://www.googleapis.com/auth/userinfo.profile(获取用户基本信息)https://www.googleapis.com/auth/userinfo.email(获取用户邮箱)https://www.googleapis.com/auth/gmail.readonly(只读访问Gmail邮件)
- 在「测试用户」列表中添加你要测试的邮箱账号(未发布的应用只能让测试用户登录)。
- 确认OAuth客户端ID配置:检查你的Web应用客户端ID,确保授权重定向URI和本地开发地址一致(比如
http://localhost:3000)。
二、代码修正
核心问题是登录时没有请求Gmail API的访问权限,需要调整useGoogleLogin的配置,并优化邮件获取逻辑:
修正后的完整代码
import React, { useState, useEffect } from 'react' import { googleLogout, useGoogleLogin, TokenResponse, } from '@react-oauth/google' import axios from 'axios' interface UserProfile { picture: string name: string email: string } interface GmailMessage { id: string threadId: string } const GoogleAuth: React.FC = () => { const [user, setUser] = useState<TokenResponse | null>(null) const [profile, setProfile] = useState<UserProfile | null>(null) const [inboxMessages, setInboxMessages] = useState<GmailMessage[]>([]) // 登录时指定所需权限范围 const login = useGoogleLogin({ scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/gmail.readonly', onSuccess: (tokenResponse) => setUser(tokenResponse), onError: (error) => console.log('登录失败:', error), }) useEffect(() => { if (user) { // 获取用户基础信息 axios .get('https://www.googleapis.com/oauth2/v1/userinfo', { headers: { Authorization: `Bearer ${user.access_token}`, }, }) .then((res) => setProfile(res.data)) .catch((err) => console.log(err)) // 获取收件箱邮件列表 fetchInboxMessages(user.access_token) } }, [user]) const logOut = () => { googleLogout() setProfile(null) setInboxMessages([]) } // 获取收件箱邮件(带分页参数,避免返回过多数据) const fetchInboxMessages = async (accessToken: string) => { try { const response = await axios.get( 'https://www.googleapis.com/gmail/v1/users/me/messages', { headers: { Authorization: `Bearer ${accessToken}`, }, params: { maxResults: 10, // 只返回最新10封邮件 labelIds: 'INBOX' // 限定只获取收件箱邮件 } }, ) setInboxMessages(response.data.messages || []) console.log('收件箱邮件:', response.data) } catch (error) { console.error('获取邮件失败:', error) } } // 可选:获取单封邮件的详细内容 const fetchMessageDetail = async (messageId: string, accessToken: string) => { try { const response = await axios.get( `https://www.googleapis.com/gmail/v1/users/me/messages/${messageId}`, { headers: { Authorization: `Bearer ${accessToken}`, params: { format: 'full' // 获取完整邮件内容,可选raw/minimal/full } } } ) console.log('邮件详情:', response.data) } catch (error) { console.error('获取邮件详情失败:', error) } } return ( <div style={{ padding: '20px' }}> {profile ? ( <div> <img src={profile.picture} alt="用户头像" style={{ borderRadius: '50%', width: '80px' }} /> <h3>已登录用户</h3> <p>姓名: {profile.name}</p> <p>邮箱: {profile.email}</p> <button onClick={logOut} style={{ margin: '10px 0' }}>退出登录</button> <h4>收件箱邮件列表</h4> {inboxMessages.length > 0 ? ( <ul> {inboxMessages.map(msg => ( <li key={msg.id} onClick={() => fetchMessageDetail(msg.id, user!.access_token)} style={{ cursor: 'pointer', padding: '8px', borderBottom: '1px solid #eee' }}> 邮件ID: {msg.id} </li> ))} </ul> ) : ( <p>暂无邮件数据</p> )} </div> ) : ( <button onClick={() => login()}>使用Google登录 🚀 </button> )} </div> ) } export default GoogleAuth
关键修改点
- 添加权限范围:在
useGoogleLogin中新增scope参数,明确请求Gmail只读权限,这是解决403错误的核心。 - 优化API请求:获取邮件时添加
maxResults和labelIds参数,减少返回数据量并限定范围。 - 新增邮件详情获取函数:可选功能,用于查看单封邮件的具体内容。
注意事项
- 如果仍出现403错误,检查测试用户是否正确添加,或者清除浏览器的OAuth缓存(可以通过浏览器设置移除相关应用授权)。
- 正式发布应用前,需要将OAuth同意屏幕从测试模式切换到生产模式,并通过Google的审核。
内容的提问来源于stack exchange,提问作者Naveen Singh
相关产品推荐
相关产品推荐

