Socialite é uma ferramenta de autenticação OAuth2. É inspirado em laravel/socialite e você pode usá-lo facilmente em qualquer projeto PHP. Documento em inglês
A ferramenta agora suporta as seguintes plataformas: Facebook, Github, Google, Linkedin, Outlook, QQ, TAPD, Alipay, Taobao, Baidu, DingTalk, Weibo, WeChat, Douyin, Feishu, Lark, Douban, Enterprise WeChat, Tencent Cloud, Line, Gitee, codificação.
Se você gosta dos meus projetos e quer me apoiar, clique aqui ❤️
PHP >= 8.0.2
composer require " overtrue/socialite " -vvv
Os usuários só precisam criar variáveis de configuração correspondentes e, em seguida, usar ferramentas para criar aplicativos de autenticação para cada plataforma e obter facilmente o access_token da plataforma e informações relacionadas ao usuário. Para obter detalhes sobre a lógica de implementação da ferramenta, consulte os documentos OAuth2 de cada plataforma principal.
O uso da ferramenta é dividido basicamente nas seguintes etapas:
Um pacote de integração mais conveniente criado para usuários do Laravel: overtrue/laravel-socialite
authorize.php
: permite que o usuário vá para a autenticação da plataforma
<?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]"
. . .
Ele funciona imediatamente definindo os mesmos pares de valores-chave para cada plataforma: client_id
, client_secret
, redirect
.
Exemplo:
$ 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 ' ,
],
];
Você pode nomear cada plataforma com o nome que desejar, como foo
. Depois de usar o método alias, você precisa definir uma chave provider
adicional na configuração, para informar ao kit de ferramentas como encontrar corretamente o programa desejado:
$ 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 ' );
Você pode criar facilmente aplicativos de provedores de serviços personalizados seguindo estes dois pontos:
Usar criador personalizado
Conforme mostrado no código a seguir, o nome do provedor de serviços é definido para o aplicativo foo, mas a própria ferramenta ainda não o suporta, então o criador extend()
é usado para criar uma instância do provedor de serviços na forma de um encerramento função.
$ 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 ' );
Importante
? Sua classe de provedor de serviços customizada deve implementar a interface OvertrueSocialiteContractsProviderInterface
class MyCustomProvider implements Overtrue Socialite Contracts ProviderInterface
{
//...
}
Em seguida, defina o nome da classe provider
para que as ferramentas possam encontrar a classe e instanciá-la:
$ 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 ' );
Diferentes plataformas possuem diferentes métodos de configuração. Para garantir o funcionamento normal da ferramenta, certifique-se de que a configuração da plataforma que você está usando está definida conforme o esperado.
Por favor configure da seguinte forma
$ 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 (); // "安正超"
. . .
Atualmente, esta ferramenta oferece suporte apenas ao método de autenticação de chave privada pessoal RSA2.
Como mostra a documentação
Nota: Esta ferramenta suporta apenas código QR para conectar-se a sites de terceiros para obter informações do usuário (opeid, unionid e apelido)
$ 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 (); // "安正超"
. . .
Nota: Ao usar o serviço Douyin, se você quiser usar access_token diretamente para obter informações do usuário, defina primeiro o openid. Chame
withOpenId()
primeiro e depoisuserFromToken()
$ 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 ' );
Nota: Ao usar o serviço
头条
, se você quiser usar access_token diretamente para obter informações do usuário, defina primeiro o openid. ChamewithOpenId()
primeiro e depoisuserFromToken()
$ 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 ' );
Nota: Ao usar o serviço
西瓜
, se você quiser usar access_token diretamente para obter informações do usuário, defina primeiro o openid. ChamewithOpenId()
primeiro e depoisuserFromToken()
$ 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 ' );
Não há diferença em outras configurações Em termos de uso, você pode facilmente escolher o modo de redirecionamento da página de login através de withDisplay()
$ authUrl = $ socialite -> create ( ' baidu ' )-> withDisplay ( ' mobile ' )-> redirect ();
O modo popup
é o modo de uso padrão da ferramenta. basic
é o valor de escopo padrão usado.
Você pode usar o modo de aplicativo interno configurando app_ticket de algumas maneiras simples
$ 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 ' );
Você pode usar o modo de aplicativo interno configurando app_ticket de algumas maneiras simples
$ 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 ' );
Outras configurações são iguais às de outras plataformas, você pode selecionar o tipo de página de redirecionamento que deseja exibir usando withView()
$ authUrl = $ socialite -> create ( ' taobao ' )-> withView ( ' wap ' )-> redirect ();
O modo web
é o modo de exibição padrão usado pela ferramenta user_info
é o valor do escopo padrão.
Apoiamos plataformas abertas para autorizar páginas da web de plataformas de terceiros em nome de contas públicas.
Você só precisa inserir sua configuração como abaixo. As contas oficiais não necessitam de autorização.
. . .
[
' 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 ' ,
]
]
],
...
Você precisa configurar adicionalmente team_url
como o nome de domínio da sua equipe, por exemplo:
$ config = [
' coding ' => [
' team_url ' => ' https://{your-team}.coding.net ' ,
' client_id ' => ' your app id ' ,
' client_secret ' => ' your app secret ' ,
' redirect ' => ' redirect URL ' ,
]
];
Pode ser necessário definir o responseType. Você pode usar a função withResponseType
para defini-lo. O padrão é code
e também pode ser definido como 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 " ,
],
];
Você também pode usar scopes()
para definir "escopos" na solicitação antes de redirecionar o usuário. Este método substituirá todos os escopos existentes:
$ response = $ socialite -> create ( ' github ' )
-> scopes ([ ' scope1 ' , ' scope2 ' ])-> redirect ();
Você também pode definir 'redireite_uri' dinamicamente, você pode usar o seguinte método para alterar o URL redirect_uri
:
$ url = ' your callback url. ' ;
$ socialite -> redirect ( $ url );
// or
$ socialite -> withRedirectUrl ( $ url )-> redirect ();
Seu aplicativo pode evitar ataques de falsificação de solicitação entre sites (CSFR) usando um parâmetro de status para garantir que a resposta pertença ao mesmo usuário que iniciou a solicitação. Os ataques CSFR ocorrem quando um invasor mal-intencionado engana um usuário para que execute ações indesejadas que somente o usuário tem permissão para executar em um aplicativo da web confiável, tudo isso sem envolver ou avisar o usuário.
Aqui está um exemplo minimalista de como fornecer estado pode tornar seu aplicativo mais seguro. Neste exemplo, usamos o ID da sessão como parâmetro de estado, mas você pode usar qualquer lógica que desejar para criar um valor para o estado.
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
do retorno de chamadaDepois que o usuário autorizar seu aplicativo, ele será redirecionado de volta para o redirect_uri do seu aplicativo. O servidor OAuth retorna os parâmetros de status inalterados. Verifique se o status fornecido no redirect_uri corresponde ao status gerado pela aplicação:
<?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
Veja mais documentação sobre parâmetros state
Para incluir quaisquer parâmetros opcionais na solicitação, chame o método with()
passando um array associativo dos valores que você deseja definir:
$ 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 "
}
}
Você pode obter o atributo user como uma chave de array assim:
$ user [ ' id ' ]; // 1472352
$ user [ ' nickname ' ]; // "overtrue"
$ user [ ' name ' ]; // "安正超"
$ user [ ' email ' ]; // "[email protected]"
. . .
Ou use o método do objeto 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()
retorna um array .
O método $user->getTokenResponse()
retornará um array contendo a resposta retornada da API ao adquirir o token.
Nota: Este método retorna apenas um array válido quando você usa
userFromCode()
, caso contrário, retornará nulo porqueuserFromToken()
não possui uma resposta HTTP de token.
$ accessToken = ' xxxxxxxxxxx ' ;
$ user = $ socialite -> userFromToken ( $ accessToken );
Quer saber como construir um pacote de extensão PHP do zero?
Por favor, preste atenção ao meu curso prático, onde compartilharei algumas experiências de desenvolvimento de extensões - "Tutorial prático do pacote de extensões PHP - do início ao lançamento"
MIT