Socialite est un outil d'authentification OAuth2. Il est inspiré de laravel/socialite et vous pouvez facilement l'utiliser dans n'importe quel projet PHP. document anglais
L'outil prend désormais en charge les plateformes suivantes : Facebook, Github, Google, Linkedin, Outlook, QQ, TAPD, Alipay, Taobao, Baidu, DingTalk, Weibo, WeChat, Douyin, Feishu, Lark, Douban, Enterprise WeChat, Tencent Cloud, Line, Gîte, Codage.
Si mes projets vous plaisent et que vous souhaitez me soutenir, cliquez ici ❤️
PHP >= 8.0.2
composer require " overtrue/socialite " -vvv
Les utilisateurs doivent uniquement créer les variables de configuration correspondantes, puis utiliser des outils pour créer des applications d'authentification pour chaque plate-forme et obtenir facilement le jeton d'accès de la plate-forme et les informations relatives à l'utilisateur. Pour plus de détails sur la logique de mise en œuvre de l'outil, veuillez vous référer aux documents OAuth2 de chaque plateforme majeure.
L'utilisation de l'outil est grossièrement divisée en les étapes suivantes :
Un package d'intégration plus pratique créé pour les utilisateurs de Laravel : overtrue/laravel-socialite
authorize.php
: laisser l'utilisateur accéder à l'authentification de la plateforme
<?php
use Overtrue Socialite SocialiteManager ;
$ config = [
' github ' => [
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/socialite/callback.php ' ,
],
];
$ socialite = new SocialiteManager ( $ config );
$ url = $ socialite -> create ( ' github ' )-> redirect ();
return redirect ( $ url );
callback.php
:
<?php
use Overtrue Socialite SocialiteManager ;
$ config = [
' github ' => [
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/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 (); // "[email protected]"
. . .
Cela fonctionne immédiatement en définissant les mêmes paires clé-valeur pour chaque plate-forme : client_id
, client_secret
, redirect
.
Exemple:
$ config = [
' weibo ' => [
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/socialite/callback.php ' ,
],
' facebook ' => [
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/socialite/callback.php ' ,
],
];
Vous pouvez nommer chaque plate-forme avec le nom de votre choix, par exemple foo
. Après avoir utilisé la méthode alias, vous devez définir une clé provider
supplémentaire dans la configuration, afin d'indiquer à la boîte à outils comment trouver correctement le programme souhaité :
$ config = [
// 为 github 应用起别名为 foo
' foo ' => [
' provider ' => ' github ' , // <-- provider name
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/socialite/callback.php ' ,
],
// 另外一个名字叫做 bar 的 github 应用
' bar ' => [
' provider ' => ' github ' , // <-- provider name
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/socialite/callback.php ' ,
],
//...
];
$ socialite = new SocialiteManager ( $ config );
$ appFoo = $ socialite -> create ( ' foo ' );
$ appBar = $ socialite -> create ( ' bar ' );
Vous pouvez facilement créer des applications à partir de fournisseurs de services personnalisés en suivant ces deux points :
Utiliser un créateur personnalisé
Comme le montre le code suivant, le nom du fournisseur de services est défini pour l'application foo, mais l'outil lui-même ne le prend pas encore en charge, donc le créateur extend()
est utilisé pour créer une instance du fournisseur de services sous la forme d'une fermeture. fonction.
$ config = [
' foo ' => [
' provider ' => ' myprovider ' , // <-- 一个工具还未支持的服务提供程序
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/socialite/callback.php ' ,
],
];
$ socialite = new SocialiteManager ( $ config );
$ socialite -> extend ( ' myprovider ' , function ( array $ config ) {
return new MyCustomProvider ( $ config );
});
$ app = $ socialite -> create ( ' foo ' );
Important
? Votre classe de fournisseur de services personnalisée doit implémenter l'interface OvertrueSocialiteContractsProviderInterface
class MyCustomProvider implements Overtrue Socialite Contracts ProviderInterface
{
//...
}
Ensuite, définissez le nom de classe provider
afin que les outils puissent trouver la classe et l'instancier :
$ config = [
' foo ' => [
' provider ' => MyCustomProvider::class, // <-- 类名
' client_id ' => ' your-app-id ' ,
' client_secret ' => ' your-app-secret ' ,
' redirect ' => ' http://localhost/socialite/callback.php ' ,
],
];
$ socialite = new SocialiteManager ( $ config );
$ app = $ socialite -> create ( ' foo ' );
Différentes plates-formes ont des méthodes de configuration différentes. Afin de garantir le fonctionnement normal de l'outil, veuillez vous assurer que la configuration de la plate-forme que vous utilisez est définie comme prévu.
Veuillez configurer comme suit
$ config = [
' alipay ' => [
// 这个键名还能像官方文档那样叫做 'app_id'
' client_id ' => ' your-app-id ' ,
// 请根据官方文档,在官方管理后台配置 RSA2
// 注意: 这是你自己的私钥
// 注意: 不允许私钥内容有其他字符
// 建议: 为了保证安全,你可以将文本信息从磁盘文件中读取,而不是在这里明文
' rsa_private_key ' => ' your-rsa-private-key ' ,
// 确保这里的值与你在服务后台绑定的地址值一致
// 这个键名还能像官方文档那样叫做 'redirect_url'
' redirect ' => ' http://localhost/socialite/callback.php ' ,
// 沙箱模式接入地址见 https://opendocs.alipay.com/open/220/105337#%E5%85%B3%E4%BA%8E%E6%B2%99%E7%AE%B1
' sandbox ' => false ,
]
. . .
];
$ socialite = new SocialiteManager ( $ config );
$ user = $ socialite -> create ( ' alipay ' )-> userFromCode ( ' here is auth code ' );
// 详见文档后面 "User interface"
$ user -> getId (); // 1472352
$ user -> getNickname (); // "overtrue"
$ user -> getUsername (); // "overtrue"
$ user -> getName (); // "安正超"
. . .
Cet outil ne prend actuellement en charge que la méthode d'authentification par clé privée personnelle RSA2.
Comme le montre la documentation
Remarque : Cet outil prend uniquement en charge le code QR pour se connecter à des sites Web tiers afin d'obtenir des informations sur l'utilisateur (opeid, unionid et pseudo).
$ 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 ' );
// 详见文档后面 "User interface"
$ user -> getId (); // 1472352
$ user -> getNickname (); // "overtrue"
$ user -> getUsername (); // "overtrue"
$ user -> getName (); // "安正超"
. . .
Remarque : lorsque vous utilisez le service Douyin, si vous souhaitez utiliser directement access_token pour obtenir des informations utilisateur, veuillez d'abord définir openid. Appelez d'abord
withOpenId()
puisuserFromToken()
$ 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 ' );
Remarque : lorsque vous utilisez le service
头条
, si vous souhaitez utiliser directement access_token pour obtenir des informations utilisateur, veuillez d'abord définir openid. Appelez d'abordwithOpenId()
puisuserFromToken()
$ config = [
' toutiao ' => [
' client_id ' => ' your app id ' ,
' client_secret ' => ' your app secret ' ,
' redirect ' => ' redirect URL '
]
];
$ socialite = new SocialiteManager ( $ config );
$ user = $ socialite -> create ( ' toutiao ' )-> userFromCode ( ' here is auth code ' );
$ user = $ socialite -> create ( ' toutiao ' )-> withOpenId ( ' openId ' )-> userFromToken ( ' here is the access token ' );
Remarque : lorsque vous utilisez le service
西瓜
, si vous souhaitez utiliser directement access_token pour obtenir des informations utilisateur, veuillez d'abord définir openid. Appelez d'abordwithOpenId()
puisuserFromToken()
$ config = [
' xigua ' => [
' client_id ' => ' your app id ' ,
' client_secret ' => ' your app secret ' ,
' redirect ' => ' redirect URL '
]
];
$ socialite = new SocialiteManager ( $ config );
$ user = $ socialite -> create ( ' xigua ' )-> userFromCode ( ' here is auth code ' );
$ user = $ socialite -> create ( ' xigua ' )-> withOpenId ( ' openId ' )-> userFromToken ( ' here is the access token ' );
Il n'y a aucune différence dans les autres configurations. En termes d'utilisation, vous pouvez facilement choisir le mode de redirection de la page de connexion via withDisplay()
$ authUrl = $ socialite -> create ( ' baidu ' )-> withDisplay ( ' mobile ' )-> redirect ();
Le mode popup
est le mode d'utilisation par défaut dans l'outil. basic
est la valeur de portée par défaut utilisée.
Vous pouvez utiliser le mode application interne en configurant app_ticket de manière simple
$ config = [
' feishu ' => [
// or 'app_id'
' client_id ' => ' your app id ' ,
// or 'app_secret'
' client_secret ' => ' your app secret ' ,
// or 'redirect_url'
' redirect ' => ' redirect URL ' ,
// 如果你想使用使用内部应用的方式获取 app_access_token
// 对这个键设置了 'internal' 值那么你已经开启了内部应用模式
' 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 ' );
Vous pouvez utiliser le mode application interne en configurant app_ticket de manière simple
$ config = [
' lark ' => [
// or 'app_id'
' client_id ' => ' your app id ' ,
// or 'app_secret'
' client_secret ' => ' your app secret ' ,
// or 'redirect_url'
' redirect ' => ' redirect URL ' ,
// 如果你想使用使用内部应用的方式获取 app_access_token
// 对这个键设置了 'internal' 值那么你已经开启了内部应用模式
' app_mode ' => ' internal '
]
];
$ socialite = new SocialiteManager ( $ config );
$ larkDriver = $ socialite -> create ( ' lark ' );
$ larkDriver -> withInternalAppMode ()-> userFromCode ( ' here is code ' );
$ larkDriver -> withDefaultMode ()-> withAppTicket ( ' app_ticket ' )-> userFromCode ( ' here is code ' );
Les autres configurations sont les mêmes que sur les autres plateformes, vous pouvez sélectionner le type de page de redirection que vous souhaitez afficher en utilisant withView()
$ authUrl = $ socialite -> create ( ' taobao ' )-> withView ( ' wap ' )-> redirect ();
Le mode web
est le mode d'affichage par défaut utilisé par l'outil user_info
est la valeur de portée par défaut.
Nous prenons en charge les plateformes ouvertes pour autoriser les pages Web de plateformes tierces au nom de comptes publics.
Il vous suffit de saisir votre configuration comme ci-dessous. Les comptes officiels ne nécessitent pas d'autorisation.
. . .
[
' wechat ' =>
[
' client_id ' => ' client_id ' ,
' client_secret ' => ' client_secret ' ,
' redirect ' => ' redirect-url ' ,
// 开放平台 - 第三方平台所需
' component ' => [
// or 'app_id', 'component_app_id' as key
' id ' => ' component-app-id ' ,
// or 'app_token', 'access_token', 'component_access_token' as key
' token ' => ' component-access-token ' ,
]
]
],
...
Vous devez également configurer team_url
comme nom de domaine de votre équipe, par exemple :
$ config = [
' coding ' => [
' team_url ' => ' https://{your-team}.coding.net ' ,
' client_id ' => ' your app id ' ,
' client_secret ' => ' your app secret ' ,
' redirect ' => ' redirect URL ' ,
]
];
Vous devrez peut-être définir le type de réponse. Vous pouvez utiliser la fonction withResponseType
pour le définir. La valeur par défaut est code
et elle peut également être définie sur id_token
ou code
& id_token
https://developer.paypal.com/docs/log-in-with-paypal/integrate/generate-button/
$ config = [
' paypal ' => [
' client_id ' => ' AT****************** ' ,
' client_secret ' => ' EK************** ' ,
' sandbox ' => false ,
' redirect_url ' => " nativexo://paypalpay " ,
],
];
Vous pouvez également utiliser scopes()
pour définir des « portées » sur la requête avant de rediriger l'utilisateur. Cette méthode écrasera toutes les étendues existantes :
$ response = $ socialite -> create ( ' github ' )
-> scopes ([ ' scope1 ' , ' scope2 ' ])-> redirect ();
Vous pouvez également définir ' redirect_uri ' de manière dynamique, vous pouvez utiliser la méthode suivante pour modifier l'URL redirect_uri
:
$ url = ' your callback url. ' ;
$ socialite -> redirect ( $ url );
// or
$ socialite -> withRedirectUrl ( $ url )-> redirect ();
Votre application peut empêcher les attaques CSFR (cross-site request forgery) en utilisant un paramètre d'état pour garantir que la réponse appartient au même utilisateur qui a initié la demande. Les attaques CSFR se produisent lorsqu'un attaquant malveillant incite un utilisateur à effectuer des actions indésirables que seul l'utilisateur est autorisé à effectuer sur une application Web de confiance, le tout sans impliquer ni avertir l'utilisateur.
Voici un exemple minimaliste de la manière dont le fait de fournir un état peut rendre votre application plus sécurisée. Dans cet exemple, nous utilisons l'ID de session comme paramètre d'état, mais vous pouvez utiliser n'importe quelle logique pour créer une valeur pour l'état.
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
du rappelUne fois que l'utilisateur autorise votre application, il sera redirigé vers le redirect_uri de votre application. Le serveur OAuth renvoie les paramètres d'état inchangés. Vérifiez que le statut fourni dans redirect_uri correspond au statut généré par l'application :
<?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
Afficher plus de documentation sur les paramètres state
Pour inclure des paramètres facultatifs dans la requête, appelez la méthode with()
en passant un tableau associatif des valeurs que vous souhaitez définir :
$ response = $ socialite -> create ( ' google ' )
-> with ([ ' hd ' => ' example.com ' ])-> redirect ();
$ user = $ socialite -> create ( ' github ' )-> userFromCode ( $ code );
{
"id" : 1472352 ,
"nickname" : " overtrue " ,
"name" : "安正超" ,
"email" : " [email protected] " ,
"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 "
}
}
Vous pouvez obtenir l'attribut utilisateur sous forme de clé de tableau comme ceci :
$ user [ ' id ' ]; // 1472352
$ user [ ' nickname ' ]; // "overtrue"
$ user [ ' name ' ]; // "安正超"
$ user [ ' email ' ]; // "[email protected]"
. . .
Ou utilisez la méthode de l'objet User
:
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 ();
$user->getRaw()
renvoie un tableau .
La méthode $user->getTokenResponse()
renverra un tableau contenant la réponse renvoyée par l'API lors de l'acquisition du jeton.
Remarque : Cette méthode ne renvoie un tableau valide que lorsque vous utilisez
userFromCode()
, sinon elle renverra null caruserFromToken()
n'a pas de réponse HTTP de jeton.
$ accessToken = ' xxxxxxxxxxx ' ;
$ user = $ socialite -> userFromToken ( $ accessToken );
Vous vous demandez comment créer un package d’extension PHP à partir de zéro ?
Veuillez prêter attention à mon cours pratique, dans lequel je partagerai une expérience de développement d'extensions - "Tutoriel pratique du pack d'extensions PHP - Du démarrage à la sortie"
MIT