Java实现集成Google邮箱第三方登录
前言
目前最新版Google api验证授权基本使用OAuth 2.0,Google OAuth 2.0 API是一个身份验证和授权协议,允许用户使用他们的Google账户进行第三方应用程序的访问和授权。OAuth 2.0是一种开放的标准协议,用于在应用程序之间安全地共享用户数据。使用Google OAuth 2.0 API,应用程序可以向用户请求授权来访问他们的Google账户信息,例如个人资料信息和联系人列表。一旦用户授权,应用程序可以使用OAuth 2.0令牌访问Google API,并获取用户数据。
注意:国内访问google需要架梯子。请科学上网,不然会出现api请求超时的情况
一、注册开发者账号
1、登录Google服务开发者平台,注册账号
登录Google服务开发者平台,官网地址:https://developers.google.com
2、创建OAuth 2.0客户端ID
- 登录Google Cloud Console:访问https://console.cloud.google.com/并使用您的Google账户登录。
- 创建项目:如果您还没有创建项目,请单击“选择项目”按钮,然后单击“新建项目”按钮。按照指示创建项目。
- 导航到API和服务:在左侧菜单中,单击“API和服务”。
- 创建凭据:单击“凭据”选项卡,然后单击“创建凭据”按钮。在下拉菜单中,选择“OAuth客户端ID”。
- 配置OAuth客户端ID:在“应用程序类型”下,选择“web 应用”。
- 保存客户端ID,
执行本地测试或开发时,您必须将 http://localhost 和 http://localhost:<端口号> 都添加到已获授权的 JavaScript 来源框中
- 配置同意屏幕:单击“创建”按钮。在“同意屏幕”选项卡下,输入应用程序名称和您的隐私政策URL。
二、代码实例
可以参考 官方API:https://developers.google.com/identity/gsi/web/guides/overview?hl=zh-cn,里面有很多种实现方法,我这里列举其中一种实现方法,使用前端html+后端回调接口实现功能
1、前端代码
a、加载客户端库
普通html页面这样加载使用
<script src="https://accounts.google.com/gsi/client?hl=en" async></script>
vue页面可以这样加载使用
created() { const oScript = document.createElement('script'); oScript.src = 'https://accounts.google.com/gsi/client?hl=en'; document.body.appendChild(oScript); },
其中参数?hl=后面接的是语言,这里使用英语做示例
b、页面使用
在登录页面添加以下html代码
<div id="g_id_onload"
data-client_id="步骤二生成的客户端ID"
data-context="signin"
data-ux_mode="popup"
data-login_uri="后端接收登录回调的接口,例如http://localhost:8088/googleLogin"
data-auto_prompt="false">
</div>
<div class="g_id_signin"
data-type="standard"
data-shape="rectangular"
data-theme="outline"
data-text="signin_with"
data-size="large"
data-locale="en-US"
data-logo_alignment="left">
</div>
这里可以自定义按钮样式以及按钮参数,详情可参考官网地址:https://developers.google.com/identity/gsi/web/reference/html-reference?hl=zh-cn
其中data-login_uri的回调接口需要添加到Google服务已获授权的重定向 URI里,否则授权会异常
2、后端代码
添加所需的依赖项
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.32.1</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.32.1</version>
</dependency>
编写Java代码
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
...
@PostMapping("/googleLogin")
public void googleLogin(@RequestParam("credential") String credential){
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new GsonFactory())
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(步骤二生成的客户端ID))
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
// (Receive idTokenString by HTTPS POST)
// 这里验证登录回调的credential完整性
GoogleIdToken idToken = verifier.verify(credential);
if (idToken != null) {
Payload payload = idToken.getPayload();
// Print user identifier
String userId = payload.getSubject();
System.out.println("User ID: " + userId);
// Get profile information from payload
String email = payload.getEmail();
boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
String name = (String) payload.get("name");
String pictureUrl = (String) payload.get("picture");
String locale = (String) payload.get("locale");
String familyName = (String) payload.get("family_name");
String givenName = (String) payload.get("given_name");
// 获取到邮箱的详细信息后,可以在这里写自己系统的登录逻辑
// Use or store profile information
// ...
} else {
System.out.println("Invalid ID token.");
}
}
踩坑记录:
本地测试一切正常,放到线上verifier.verify(credential)进行验证登录回调的credential完整性一直返回null,原因是我的服务器和Google服务器时间戳不一致,所以出现这种问题检查服务器时间戳和Google时间是否一致
三、总结登录步骤
- 前端点击Google登录按钮
- 邮箱授权后Google通过回调地址将credential授权id返回到回调接口
- 回调接口验证授权码的完整性,检查是否正确
- 如果授权完整,可以获取邮箱详情信息,从而添加自己的登录逻辑
注意事项:执行本地测试或开发时,您必须将 http://localhost 和 http://localhost:<端口号> 都添加到已获授权的 JavaScript 来源框中