ifornew / socialite
OAuth 2.0 包集合。
Requires
- php: >=7.4
- ext-json: *
- ext-openssl: *
- guzzlehttp/guzzle: ~6.0|~7.0
- symfony/http-foundation: ^4.0 || ^5.0
- symfony/psr-http-message-bridge: ^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- mockery/mockery: ~1.2
- phpunit/phpunit: ~9.0
This package is not auto-updated.
Last update: 2024-09-24 16:03:22 UTC
README
Socialite 是一个 OAuth2 认证工具。它受到 laravel/socialite 的启发,您可以在任何 PHP 项目中轻松使用它。 中文文档
该工具现在支持 Facebook、GitHub、Google、LinkedIn、Outlook、QQ、Tapd、支付宝、淘宝、百度、钉钉、微博、微信、抖音、飞书、豆瓣、企业微信、腾讯云、Line、Gitee 等平台。
如果你喜欢我的项目并想支持它,点击这里 :heart:
要求
PHP >= 7.4
安装
$ composer require "overtrue/socialite" -vvv
使用
用户只需要创建相应的配置变量,然后通过该工具为每个平台创建认证应用程序,轻松获取该平台的 access_token 和用户信息。该工具的实现逻辑参考了主要平台的 OAuth2 文档以获取详细信息。
工具的使用步骤如下
- 配置平台配置
- 使用此工具创建平台应用程序
- 让用户重定向到平台认证
- 服务器从平台接收 Code 回调,并使用 Code 交换平台上的用户信息(包括 access_token)。
为 Laravel 用户创建的包更容易集成: overtrue/laravel-socialite
authorize.php:
<?php
use Ifornew\Socialite\SocialiteManager;
$config = [
'github' => [
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
];
$socialite = new SocialiteManager($config);
$url = $socialite->create('github')->redirect();
return redirect($url);
callback.php:
<?php
use Ifornew\Socialite\SocialiteManager;
$config = [
'github' => [
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
];
$socialite = new SocialiteManager($config);
$code = request()->query('code');
$user = $socialite->create('github')->userFromCode($code);
$user->getId(); // 1472352
$user->getNickname(); // "overtrue"
$user->getUsername(); // "overtrue"
$user->getName(); // "安正超"
$user->getEmail(); // "anzhengchao@gmail.com"
...
配置
每个创建都使用相同的配置键: client_id、client_secret、redirect。
示例
$config = [
'weibo' => [
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
'facebook' => [
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
];
自定义应用名称
您可以使用任何喜欢的名称作为应用程序的名称,例如 foo,并使用 provider 键设置提供者:
$config = [
'foo' => [
'provider' => 'github', // <-- provider name
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
// another github app
'bar' => [
'provider' => 'github', // <-- provider name
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
//...
];
扩展自定义提供者
您可以从自定义提供者轻松创建应用程序,您有两种方法可以这样做
- 使用自定义创建器:如下面的代码所示,为 Foo 应用程序定义了服务提供者名称,但工具本身不支持它,因此使用创建器
extend()通过闭包函数创建服务提供者的实例。
$config = [
'foo' => [
'provider' => 'myprovider', // <-- provider name
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
];
$socialite = new SocialiteManager($config);
$socialite->extend('myprovider', function(array $config) {
return new MyCustomProvider($config);
});
$app = $socialite->create('foo');
- 使用提供者
>👋🏻 您的自定义提供者类必须实现 Ifornew\Socialite\Contracts\ProviderInterface。
class MyCustomProvider implements \Ifornew\Socialite\Contracts\ProviderInterface
{
//...
}
然后使用类名设置 provider
$config = [
'foo' => [
'provider' => MyCustomProvider::class, // <-- class name
'client_id' => 'your-app-id',
'client_secret' => 'your-app-secret',
'redirect' => 'https:///socialite/callback.php',
],
];
$socialite = new SocialiteManager($config);
$app = $socialite->create('foo');
平台
不同的平台有不同的配置方法,请检查您使用的平台设置。
支付宝
您必须具有以下配置。
$config = [
'alipay' => [
// This can also be named as 'app_id' like the official documentation.
'client_id' => 'your-app-id',
// Please refer to the official documentation, in the official management background configuration RSA2.
// Note: This is your own private key.
// Note: Do not allow the private key content to have extra characters.
// Recommendation: For security, you can read directly from the file. But here as long as the value, please remember to remove the head and tail of the decoration.
'rsa_private_key' => 'your-rsa-private-key',
// Be sure to set this value and make sure that it is the same address value as set in the official admin system.
// This can also be named as 'redirect_url' like the official documentation.
'redirect' => 'https:///socialite/callback.php',
]
...
];
$socialite = new SocialiteManager($config);
$user = $socialite->create('alipay')->userFromCode('here is auth code');
// See this documents "User interface"
$user->getId(); // 1472352
$user->getNickname(); // "overtrue"
$user->getUsername(); // "overtrue"
$user->getName(); // "安正超"
...
仅支持 RSA2 个人私钥,因此如果您想使用证书登录,请稍等。
钉钉
按照文档配置如下。
注意:它仅支持通过二维码访问第三方网站。即交换用户信息(openid、unionid 和昵称)
$config = [
'dingtalk' => [
// or 'app_id'
'client_id' => 'your app id',
// or 'app_secret'
'client_secret' => 'your app secret',
// or 'redirect_url'
'redirect' => 'redirect URL'
]
];
$socialite = new SocialiteManager($config);
$user = $socialite->create('dingtalk')->userFromCode('here is auth code');
// See this documents "User interface"
$user->getId(); // 1472352
$user->getNickname(); // "overtrue"
$user->getUsername(); // "overtrue"
$user->getName(); // "安正超"
...
抖音
注意:使用抖音创建时,如果您直接使用访问令牌获取用户信息,请先设置 openid。openid 可以在获取访问令牌时通过代码获取,因此请自动调用
userFromCode()配置您的 openid,如果先调用userFromToken(),请先调用withOpenId()
$config = [
'douyin' => [
'client_id' => 'your app id',
'client_secret' => 'your app secret',
'redirect' => 'redirect URL'
]
];
$socialite = new SocialiteManager($config);
$user = $socialite->create('douyin')->userFromCode('here is auth code');
$user = $socialite->create('douyin')->withOpenId('openId')->userFromToken('here is the access token');
百度
您可以使用 withDisplay() 来选择您想要显示的表单。
- 页面
- 弹出窗口
- 对话框
- 手机
- 电视
- 平板电脑
$authUrl = $socialite->create('baidu')->withDisplay('mobile')->redirect();
popup 模式是带有显示的默认设置。 basic 是带有权限的默认设置。
飞书
一些简单的方法可以通过内部应用模式和配置 app_ticket 来使用。
$config = [
'feishu' => [
// or 'app_id'
'client_id' => 'your app id',
// or 'app_secret'
'client_secret' => 'your app secret',
// or 'redirect_url'
'redirect' => 'redirect URL',
// if you want to use internal way to get app_access_token
// set this key by 'internal' then you already turn on the internal app mode
'app_mode' => 'internal'
]
];
$socialite = new SocialiteManager($config);
$feishuDriver = $socialite->create('feishu');
$feishuDriver->withInternalAppMode()->userFromCode('here is code');
$feishuDriver->withDefaultMode()->withAppTicket('app_ticket')->userFromCode('here is code');
淘宝
您可以使用 withView() 来选择您想要显示的表单。
$authUrl = $socialite->create('taobao')->withView('wap')->redirect();
web 模式是带有显示的默认设置。 user_info 是带有权限的默认设置。
微信
我们支持开放平台第三方平台网页授权代表公众号。
您只需输入以下配置即可。公众号授权不需要。
...
[
'wechat' =>
[
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'redirect' => 'redirect-url',
// Open Platform - Third-party Platform Need
'component' => [
'id' => 'component-app-id',
'token' => 'component-access-token', // or Using a callable as value.
]
]
],
...
一些技巧
作用域
在重定向用户之前,您还可以使用 scopes() 方法在请求上设置“权限”。此方法将覆盖所有现有权限
$response = $socialite->create('github')
->scopes(['scope1', 'scope2'])->redirect();
重定向 URL
您可能还想动态设置 redirect_uri,您可以使用以下方法来更改 redirect_uri URL
$url = 'your callback url.';
$socialite->redirect($url);
// or
$socialite->withRedirectUrl($url)->redirect();
状态
您的应用可以使用状态参数来确保响应属于由同一用户发起的请求,因此防止跨站请求伪造(CSRF)攻击。CSRF 攻击发生在恶意攻击者欺骗用户执行只有授权用户才能在受信任的 Web 应用程序上执行的不希望的操作,并且所有这些操作都不会涉及或提醒用户。
以下是提供状态如何使您的应用更安全的简单示例。在这个例子中,我们使用会话 ID 作为状态参数,但您可以使用任何您想要的逻辑来创建状态值。
使用 state 参数重定向
<?php
session_start();
$config = [
//...
];
// Assign to state the hashing of the session ID
$state = hash('sha256', session_id());
$socialite = new SocialiteManager($config);
$url = $socialite->create('github')->withState($state)->redirect();
return redirect($url);
验证回调 state
一旦用户授权了您的应用,用户将被重定向回您的应用的 redirect_uri。OAuth 服务器将返回未更改的状态参数。检查 redirect_uri 中提供的状态是否与您的应用生成状态匹配
<?php
session_start();
$state = request()->query('state');
$code = request()->query('code');
// Check the state received with current session id
if ($state != hash('sha256', session_id())) {
exit('State does not match!');
}
$user = $socialite->create('github')->userFromCode($code);
// authorized
附加参数
要将任何可选参数包含在请求中,请使用关联数组调用 with() 方法
$response = $socialite->create('google')
->with(['hd' => 'example.com'])->redirect();
用户界面
标准用户 API
$user = $socialite->create('github')->userFromCode($code);
{
"id": 1472352,
"nickname": "overtrue",
"name": "安正超",
"email": "anzhengchao@gmail.com",
"avatar": "https://avatars.githubusercontent.com/u/1472352?v=3",
"raw": {
"login": "overtrue",
"id": 1472352,
"avatar_url": "https://avatars.githubusercontent.com/u/1472352?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/overtrue",
"html_url": "https://github.com/overtrue",
...
},
"token_response": {
"access_token": "5b1dc56d64fffbd052359f032716cc4e0a1cb9a0",
"token_type": "bearer",
"scope": "user:email"
}
}
您可以根据这些数组键来检索用户属性
$user['id']; // 1472352
$user['nickname']; // "overtrue"
$user['name']; // "安正超"
$user['email']; // "anzhengchao@gmail.com"
...
或使用该方法
mixed $user->getId();
?string $user->getNickname();
?string $user->getName();
?string $user->getEmail();
?string $user->getAvatar();
?string $user->getRaw();
?string $user->getAccessToken();
?string $user->getRefreshToken();
?int $user->getExpiresIn();
?array $user->getTokenResponse();
从 OAuth API 获取原始响应
$user->getRaw() 方法将返回 API 原始响应的 数组。
使用 userFromCode() 获取令牌响应
$user->getTokenResponse() 方法将返回获取令牌(访问令牌)API 响应的 数组。
注意:此方法仅在您使用
userFromCode()时返回一个 有效的数组,否则将返回 null,因为使用userFromToken()没有令牌响应。
使用访问令牌获取用户
$accessToken = 'xxxxxxxxxxx';
$user = $socialite->userFromToken($accessToken);
享受它! :heart
参考
- 支付宝 - 用户信息授权
- 钉钉 - 扫码登录第三方网站
- 谷歌 - OpenID Connect
- GitHub - 授权 OAuth 应用
- Facebook - Graph API
- 领英 - 使用 OAuth 2.0 进行身份验证
- 微博 - OAuth 2.0 授权机制说明
- QQ - OAuth 2.0 登录 QQ
- 腾讯云 - OAuth2.0
- 微信公众平台 - OAuth 文档
- 微信开放平台 - 网站应用微信登录开发指南
- 微信开放平台 - 代表公众号发起网页授权
- 企业微信 - OAuth 文档
- 企业微信第三方应用 - OAuth 文档
- 豆瓣 - OAuth 2.0 授权机制说明
- 抖音 - 网站应用开发指南
- 飞书 - 授权说明
- Tapd - 用户授权说明
- Line - OAuth 2.0
- Gitee - OAuth 文档
由 JetBrains 支持的项目
感谢 JetBrains 善意提供许可,让我能够在这个和其他开源项目上工作。
PHP 扩展包开发
想知道如何从零开始构建 PHP 扩展包吗?
请关注我的实战课程,我将在该课程中分享一些扩展开发经验 —— 《PHP 扩展包实战教程 - 从入门到发布》
许可证
MIT
