首页> 实战笔录 >PHP开发笔记 >Hyperf Hyperf
hyperf3.1实现apple第三方网页授权登录
作者:小萝卜 2025-04-04 【 PHP Hyperf 第三方 Apple 功能 】 浏览 89
简介完整流程: 1.点击前端 Apple 登录按钮。2.用户授权后,Hyperf 会收到包含 code 的 POST 请求。3.后端通过 code 换取 access_token 并获取用户数据。4.返回用户信息或执行登录逻辑。
一、准备工作(具体请参考:Apple第三方网页授权登录-OAuth客户端创建配置流程)
-
注册 Apple 开发者账号
-
前往 Apple Developer 创建应用 ID
-
启用 "Sign In with Apple" 功能
-
-
获取必要参数
-
Service ID (客户端ID):如
com.example.service
-
Team ID:开发者团队ID
-
密钥文件 (.p8):用于生成客户端密钥
-
Key ID:生成密钥时获得的标识
-
1. 安装依赖
composer require league/oauth2-client
composer require patrickbussmann/oauth2-apple
2. 配置参数
在 config/autoload/oauth.php
中配置 Apple 参数:
<?php
return [
'apple' => [
'client_id' => env('APPLE_CLIENT_ID'), // Service ID (如 com.company.service)
'team_id' => env('APPLE_TEAM_ID'), // 开发者账号 Team ID
'key_id' => env('APPLE_KEY_ID'), // 私钥 Key ID
'redirect_uri' => env('APPLE_REDIRECT_URI'),// 回调地址
'key_path' => BASE_PATH . '/storage/apple/AuthKey.p8', // .p8 私钥文件路径
],
];
3. 创建控制器
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 apple跳转授权登录
* @author: Luobo
* @date: 2025/3/6 19:49
*/
#[GetMapping("apple")]
public function appleLogin(ResponseInterface $response)
{
$state = bin2hex(random_bytes(16)); // 防 CSRF
// 存储 state 到 redis 或缓存
$this->redis->set('oauth:apple:state:' . $state, 'valid', 300);
$provider = $this->service->getProvider();
$authUrl = $provider->getAuthorizationUrl([
'scope' => 'name email', // 请求用户姓名和邮箱
'state' => $state,
]);
return $response->redirect($authUrl);
}
/**
* @param MineFormRequest $request
* @param ResponseInterface $response
* @return \Psr\Http\Message\ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws \Psr\SimpleCache\InvalidArgumentException
* @description apple跳转授权回调地址
* @author:Luobo
* @date: 2025/3/7 10:30
*/
#[PostMapping("apple_callback")]
public function appleCallback(MineFormRequest $request,ResponseInterface $response)
{
$provider = $this->service->getProvider();
$code = $request->input('code');
$state = $request->input('state');
// 验证 state(需从 Session/Cache 中比对)
if (!$this->redis->exists('oauth:apple:state:' . $state)) {
throw new \RuntimeException(crmTrans('Invalid state'));
}
try {
$token = $provider->getAccessToken('authorization_code', ['code' => $code]);
$appleUser = $provider->getResourceOwner($token);
// 处理用户信息
$sub = $appleUser->getId();
$email = $appleUser->getEmail();
$name = $appleUser->getFirstName() . ' ' . $appleUser->getLastName();
$url = $this->service->setWebUser(['sub'=>$sub,'email'=>$email,'name'=>$name,'picture'=>'','plateform'=>'Apple'],$request);
return $response->redirect($url);
} catch (\Exception $e) {
return $response->json(['error' => $e->getMessage()], 400);
}
}
}
很赞哦! (0)