Google OAuth 2.0

Google OAuth 2.0

前言

国内网络大环境的影响,基于谷歌 API 开发产品的文章较少

而且谷歌官方 sdk 文档也是一言难尽

基于谷歌授权登录,记录一下鉴权的全流程

基于 PC Wap 做的谷歌登录,得先有授权链接后再去谷歌服务端拿用户数据

composer插曲

1
composer require google/apiclient

这里发生了一个小插曲 我们项目里依赖 google 相关 composer 包有好几个

而有些版本较老,有些版本比较新,各自依赖的 composer 版本不一致

所以执行 composer install 失败,冲突主要有两个

冲突 1

最新版依赖的 google/auth 这个包的版本比较高

项目目前其他的包依赖的 auth 版本不支持使用较新的

冲突1解决方案

当前想要安装的 google/apiclient 不用安装最新版本的包

只需要安装一个能兼容当前其他包版本相对较新的包即可

  1. 首先项目里执行 composer depends google/auth

    1
    2
    3
    4
    5
    composer depends google/auth
    google/apiclient v2.13.2 requires google/auth (^1.10)
    google/cloud-core v1.52.4 requires google/auth (^1.18)
    google/gax v1.19.1 requires google/auth (1.19.1||^1.25.0)
    google/grpc-gcp v0.2.1 requires google/auth (^1.3)

    以上面为例 会显示当前项目中依赖这个包的版本限制

    基于上面的结果找出适合的版本号 例如 1.19

访问 https://packagist.org/

搜索 google/apiclient 后右下角有标签列表

点击标签后切换到指定版本观察 require 依赖的包的版本

以上面的例子为例的话 只需要找到对应标签版本使用的 google/auth 是1.19的就可以了

最后锁定了 google/apiclient2.13.2

Packagist 是一个PHP软件包的集中式存储库

它为开发人员提供了一个方便的方式来分享和安装PHP软件包

开发人员可以将自己的PHP软件包上传到Packagist,并通过 composer 进行安装和依赖管理

冲突2

再解决冲突1后发现另外一个包也存在版本冲突问题

目前已经安装的 guzzlehttp/psr71.2 版本

同理首先项目里执行 composer depends guzzlehttp/psr7

1
2
3
4
5
6
7
8
9
10
composer depends guzzlehttp/psr7
alibabacloud/tea-oss-utils 0.3.1 requires guzzlehttp/psr7 (^1.0)
google/apiclient v2.13.2 requires guzzlehttp/psr7 (^1.8.4||^2.2.1)
google/auth v1.26.0 requires guzzlehttp/psr7 (^1.7|^2.0)
google/cloud-core v1.52.4 requires guzzlehttp/psr7 (^1.7|^2.0)
google/gax v1.19.1 requires guzzlehttp/psr7 (^1.7.0||^2)
guzzlehttp/command 1.3.0 requires guzzlehttp/psr7 (^1.9.1 || ^2.4.5)
guzzlehttp/guzzle 7.8.1 requires guzzlehttp/psr7 (^1.9.1 || ^2.5.1)
guzzlehttp/guzzle-services 1.4.0 requires guzzlehttp/psr7 (^1.9.1 || ^2.4.5)
qcloud/cos-sdk-v5 v2.6.6 requires guzzlehttp/psr7 (^1.3.1 || ^2.0)

接着执行 composer update guzzlehttp/psr7:^1.9 后可解决

要更新到哪个版本可以自行决定 能适配上面的版本即可

再回到最开始想要安装的 composer require google/apiclient:2.13.2

谷歌登录的 composer 包就此安装完毕

google 登录流程

  1. 生成一条授权链接
  2. 用户跳转过去输入谷歌账号相关信息后完成授权
  3. 接着谷歌回调到我们之前指定的地址并带过来一些参数
  4. 拿着回调参数去谷歌接口换取用户信息后完成 google 登录

生成授权链接

参考文档链接

所需的配置参数
参数名注释示例值
client_id
client_secret
auth_uri鉴权链接https://accounts.google.com/o/oauth2/auth
token_uri谷歌接口地址https://oauth2.googleapis.com/token
redirect_uris回调地址数组 可支持多个
javascript_origins数组 可支持多个

这份配置也可以直接在开发者账号下导出一个 client_secret.json

后面 sdk 类需要导出这份配置

具体可以参考官方链接

这里的配置需要跟谷歌应用里的设置相对应

php 示例代码如下

1
2
3
4
5
6
7
8
9
10
<?php
$client = new Google\Client();
$client->setAuthConfig($config); // 设置配置
$client->addScope(Google\Service\Oauth2::USERINFO_PROFILE); // 个人信息
$client->setRedirectUri('https://www.test.com/api/google/callback/pc'); // 回调地址
$client->setAccessType('offline'); // 离线使用 -> web
$client->setPrompt('consent'); // 提示用户同意
$client->setIncludeGrantedScopes(true); // 增量授权
$auth_url = $client->createAuthUrl();
?>
  • $client->setAuthConfig 这里传入的 $config 可以是数组 也可以是 json 字符串 也是上面获取的配置
  • $client->addScope 要获取用户的哪些信息
    • 可以通过 官方文档 去看下有哪些信息可以获取
    • 这次要做的是登录 所以只需要用户的基础信息
  • $client->setPrompt 设置用户提示信息
    • none 无任何提示
    • consent 提示用户同意
    • select_account 提示用户选择帐户

其他方法看注释即可

$auth_url 就是我们最后生成的授权链接 跳转过去登录谷歌账号就可以完成相关授权

官方建议服务器先处理请求,然后重定向到另一个不包含响应参数的网址

官方对 重定向链接 是有一定要求的

  • 必须是 https 链接
  • 不能是 ip 地址
  • 不能包含相对路径 /.. 或者 \..
  • 链接字符禁止有以下
    • 通配符 '*'
    • 不可打印的 ASCII 字符
    • 百分号编码无效(任何百分号编码不符合网址编码形式,即百分号后跟两个十六进制数字)
    • Null 字符(经过编码的 NULL 字符,例如%00%C0%80

处理OAuth 2.0服务器响应

文档链接

通过授权链接成功完全授权后,会带回

字段名示例值注释
code/0AfJohXkLY-PZ7frnZLnziJgpbSf6J1HUw1w6iI2O16ckLKdwArAeVBXjzMcwlaliB-QBXQ
scopeprofile https://www.googleapis.com/auth/userinfo.profile

如果授权失败会返回 https://oauth2.example.com/auth?error=access_denied

目前还不知道怎么触发,代码先做好防错机制

谷歌那边用 code 的换取 accesstoekn 结果

1
2
3
4
5
6
7
8
9
{
"access_token": "xxxxxxxxxxxxxxx",
"expires_in": 3599,
"refresh_token": "1//0gMHInvgPNP5iCgYIARAAGBASNgF-L9IrE40V0_sDYzTOweZ0bMaUFnor12DrgxKd28zThypqaQz1fxqI3guRM43PILKXASFekw",
"scope": "https://www.googleapis.com/auth/userinfo.profile",
"token_type": "Bearer",
"id_token": "xxxxxxxxxxxxxxxx",
"created": 1704960410
}

接着拿 toeken 去换取用户信息

完整 php 代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$client = new Google\Client();
$client->setAuthConfig($config); // 设置配置
$client->setRedirectUri('https://www.test.com/api/google/callback/pc'); // 回调地址
$client->setAccessType('offline'); // 离线使用 -> web
$client->setPrompt('consent'); // 提示用户同意
$client->setIncludeGrantedScopes(true); // 增量授权
$client->addScope(Oauth2::USERINFO_PROFILE); // 个人信息
$client->addScope(Oauth2::USERINFO_EMAIL); // 邮箱

$token_result = $client->fetchAccessTokenWithAuthCode($code); // 获取token的结果
$drive = new Google\Service\Oauth2($client);
$user_info = $drive->userinfo_v2_me->get(); // 获取实际的用户信息

$email = $user_info->getEmail(); // 邮箱
$name = $user_info->getName(); // 名称
$id = $user_info->getId(); // google用户id
$picture = $user_info->getPicture(); // 头像

最后基于谷歌返回用户信息做自己相对应的业务逻辑即可

感谢您的阅读,本文由 Double-c 版权所有。如若转载,请注明出处:Double-c(https://double-c.github.io/2024/01/17/google-oauth2-0/
git常用操作