首页> 实战笔录 >PHP开发笔记 >Hyperf Hyperf

hyperf3.1实现google第三方网页授权登录

作者:小萝卜 2025-04-04 浏览 97

简介总结步骤:1. 注册Google应用,获取客户端ID和密钥,配置回调URL。2. 安装OAuth2客户端和Google提供者库。3. 配置Hyperf的OAuth服务,注入GoogleProvider。4. 创建路由和控制器处理授权跳转和回调。5. 处理state参数,使用缓存存储。6. 在回调中换取访问令牌,获取用户信息。7. 处理用户登录或注册逻辑,返回应用自己的认证信息。

如果不知道怎么配置appid和key请移步:Google第三方网页授权登录-OAuth客户端创建配置流程

步骤1:安装依赖

 
composer require league/oauth2-client league/oauth2-google


步骤2:配置参数

在 config/autoload/oauth.php 中添加配置:

return [
    'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect_uri' => env('GOOGLE_REDIRECT_URI'),
    ],
];

在 .env 文件中配置参数:

GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=https://your-domain.com/auth/google/callback


步骤3:创建路由

在 config/routes.php 中添加(也可以直接在控制器使用注解路由):

use Hyperf\HttpServer\Router\Router;

Router::get('/auth/google', 'App\Controller\AuthController@redirectToGoogle');
Router::get('/auth/google/callback', 'App\Controller\AuthController@handleGoogleCallback');


步骤4:创建控制器

 

declare(strict_types=1);

namespace App\Http\Api\Controller\V1;

use App\Http\Api\Controller\Common\BaseController;
use App\Http\Common\MineFormRequest;
use App\Repository\member\TMemberRepository;
use App\Service\crm\MemberThirdAuthService;
use Hyperf\Collection\Arr;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\Redis\Redis;
use League\OAuth2\Client\Provider\Google;

#[Controller(prefix: 'third/login')]
class MemberThirdAuthController extends BaseController
{
    #[Inject]
    public Redis $redis;

    #[Inject]
    public MemberThirdAuthService $service;

    /**
     * @param ResponseInterface $response
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \Exception
     * @description  google跳转授权登录
     * @author: Luobo
     * @date: 2025/3/5 17:49
     */
    #[GetMapping(path: 'google')]
    public function googleLogin(ResponseInterface $response)
    {

        $provider = new Google([
            'clientId' => config('oauth.google.client_id'),
            'clientSecret' => config('oauth.google.client_secret'),
            'redirectUri' => config('oauth.google.redirect_uri'),
        ]);

        // 生成并保存state
        $state = bin2hex(random_bytes(16));
        $this->redis->set('oauth:google:state:' . $state, 'valid', 300);

        $authUrl = $provider->getAuthorizationUrl([
            'scope' => ['email', 'profile'],
            'state' => $state,
        ]);

        return $response->redirect($authUrl);
    }

    /**
     * @param RequestInterface $request
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
     * @description  google跳转授权回调地址
     * @author: Luobo
     * @date: 2025/3/5 17:49
     */
    #[GetMapping(path: 'google_callback')]
    public function googleCallback(MineFormRequest $request,ResponseInterface $response)
    {
        $state = $request->input('state');
        $code = $request->input('code');

        // 验证state
        if (!$this->redis->exists('oauth:google:state:' . $state)) {
            throw new \RuntimeException(crmTrans('Invalid state'));
        }

        $provider = new Google([
            'clientId' => config('oauth.google.client_id'),
            'clientSecret' => config('oauth.google.client_secret'),
            'redirectUri' => config('oauth.google.redirect_uri'),
        ]);

        // 获取访问令牌
        $token = $provider->getAccessToken('authorization_code', ['code' => $code]);

        // 获取用户信息
        $info = $provider->getResourceOwner($token)?->toArray();
        if(empty($info)){
            throw new \RuntimeException(crmTrans('Invalid user'));
        }

        $userInfo = [
            'sub'=>Arr::get($info,'sub',''),
            'email'=>Arr::get($info,'email',''),
            'name'=>Arr::get($info,'name',''),
            'picture'=>Arr::get($info,'picture',''),
            'plateform'=>'Google'
        ];
        $url = $this->service->setWebUser($userInfo,$request);

        return $response->redirect($url);

    }
}


在 Hyperf 3.1 中调用 Google 登录(基于 OAuth 2.0 协议)时,能获取的用户信息取决于你申请的权限范围(Scopes)以及用户授权的具体内容。以下是常见的可获取信息及相关实现说明:

1. 默认信息(OpenID Connect 基本范围)

当使用 openid 作用域时,Google 会返回以下基本信息(无需额外权限申请):

sub: 用户的唯一标识符(Subject Identifier)

name: 用户的完整姓名(如 "John Doe")

given_name: 用户的名字(如 "John")

family_name: 用户的姓氏(如 "Doe")

picture: 用户头像的公开 URL

locale: 用户的语言或地区偏好(如 "en" 或 "zh-CN")

2. 扩展信息(需申请额外权限)

通过添加更多作用域(Scopes),可以获取更多用户数据:

(1)作用域 email

email: 用户的注册邮箱地址(如 john.doe@gmail.com)

email_verified: 布尔值,表示邮箱是否已验证

(2)作用域 profile

gender: 用户的性别(如 "male" 或 "female")

birthdate: 用户的出生日期(格式可能为 "YYYY-MM-DD" 或 "0000-00-00")

zoneinfo: 用户的时区(如 "Europe/Paris")

hd: 用户的 Google Workspace 域名(仅适用于企业用户,如 "company.com")

(3)其他作用域

地址信息(需 https://www.googleapis.com/auth/user.addresses.read):用户的物理地址(街道、城市、国家等)。

电话号码(需 https://www.googleapis.com/auth/user.phonenumbers.read):用户的电话号码。

3.更多权限:

Google 提供其他高级权限(如访问云端硬盘、日历等),但需用户明确授权且应用需通过审核。

很赞哦! (1)

文章评论

    高端网站建设