GithubHelp home page GithubHelp logo

overtrue / socialite Goto Github PK

View Code? Open in Web Editor NEW
1.3K 38.0 236.0 448 KB

Socialite is an OAuth2 Authentication tool. It is inspired by laravel/socialite, you can easily use it without Laravel.

License: MIT License

PHP 100.00%
socialite oauth laravel login oauth2-authentication facebook google linkedin social-login wechat

socialite's Introduction

Socialite

Socialite 是一个 OAuth2 认证工具。 它的灵感来源于 laravel/socialite , 你可以很轻易的在任何 PHP 项目中使用它。英文文档

GitHub release (latest SemVer) GitHub License Packagist Downloads

Sponsor me

该工具现已支持平台有:Facebook,Github,Google,Linkedin,Outlook,QQ,TAPD,支付宝,淘宝,百度,钉钉,微博,微信,抖音,飞书,Lark,豆瓣,企业微信,腾讯云,Line,Gitee,Coding。

如果你喜欢我的项目并想支持我,点击这里 ❤️

版本要求

PHP >= 8.0.2

安装

$ composer require "overtrue/socialite" -vvv

使用指南

用户只需要创建相应配置变量,然后通过工具为各个平台创建认证应用,并轻松获取该平台的 access_token 和用户相关信息。工具实现逻辑详见参照各大平台 OAuth2 文档。

工具使用大致分为以下几步:

  1. 配置平台设置
  2. 创建对应平台应用
  3. 让用户跳转至平台认证
  4. 服务器收到平台回调 Code,使用 Code 换取平台处用户信息(包括 access_token)

为 Laravel 用户创建的更方便的整合的包: overtrue/laravel-socialite

authorize.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);

$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]"
...

配置

为每个平台设置相同的键值对后就能开箱即用:client_id, client_secret, redirect.

示例:

$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',
  ],
];

自定义应用名

你可以使用任意你喜欢的名字对每个平台进行命名,比如说 foo, 采用别名的方法后需要在配置中多设置一个 provider 键,这样才能告诉工具包如何正确找到你想要的程序:

$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');

扩展自定义服务提供程序

你可以很容易的从自定义的服务提供中创建应用,只需要遵循如下两点:

  1. 使用自定义创建器

    如下代码所示,为 foo 应用定义了服务提供名,但是工具本身还未支持,所以使用创建器 extend(),以闭包函数的形式为该服务提供创建一个实例。

$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');
  1. 使用服务提供类

👋🏻 你的自定义服务提供类必须实现Overtrue\Socialite\Contracts\ProviderInterface 接口

class MyCustomProvider implements \Overtrue\Socialite\Contracts\ProviderInterface 
{
    //...
}

接下来为 provider 设置该类名让工具可以找到该类并实例化:

$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');

平台

不同的平台有不同的配置方法,为了确保工具的正常运行,所以请确保你所使用的平台的配置都是如期设置的。

请按如下方式配置

$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();      // "安正超"
...

本工具暂时只支持 RSA2 个人私钥认证方式。

如文档所示

注意:该工具仅支持 QR code 连接到第三方网站,用来获取用户信息(opeid, unionid 和 nickname)

$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();      // "安正超"
...

注意: 使用抖音服务提供的时候,如果你想直接使用 access_token 获取用户信息时,请先设置 openid。 先调用 withOpenId() 再调用 userFromToken()

$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');

注意: 使用头条服务提供的时候,如果你想直接使用 access_token 获取用户信息时,请先设置 openid。 先调用 withOpenId() 再调用 userFromToken()

$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');

注意: 使用西瓜服务提供的时候,如果你想直接使用 access_token 获取用户信息时,请先设置 openid。 先调用 withOpenId() 再调用 userFromToken()

$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');

其他配置没啥区别,在用法上,可以很轻易的选择重定向登录页面的模式,通过 withDisplay()

  • **page:**全屏形式的授权页面 (默认),适用于 web 应用。
  • popup: 弹框形式的授权页面,适用于桌面软件应用和 web 应用。
  • dialog: 浮层形式的授权页面,只能用于站内 web 应用。
  • mobile: Iphone/Android 等智能移动终端上用的授权页面,适用于 Iphone/Android 等智能移动终端上的应用。
  • tv: 电视等超大显示屏使用的授权页面。
  • pad: IPad/Android 等智能平板电脑使用的授权页面。
$authUrl = $socialite->create('baidu')->withDisplay('mobile')->redirect();

popup 模式是工具内默认的使用模式。basic 是默认使用的 scopes 值。

通过一些简单的方法配置 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',

        // 如果你想使用使用内部应用的方式获取 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');

通过一些简单的方法配置 app_ticket 就能使用内部应用模式

$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');

其他配置与其他平台的一样,你能选择你想要展示的重定向页面类型通过使用 withView()

$authUrl = $socialite->create('taobao')->withView('wap')->redirect();

web 模式是工具默认使用的展示方式, user_info 是默认使用的 scopes 范围值。

我们支持开放平台代表公众号进行第三方平台网页授权。

你只需要像下面这样输入你的配置。官方账号不需要授权。

...
[
    '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',
            ]
        ]
],
...

您需要额外配置 team_url 为您的团队域名,例如:

$config = [
    'coding' => [
        'team_url' => 'https://{your-team}.coding.net', 
        'client_id' => 'your app id',
        'client_secret' => 'your app secret',
        'redirect' => 'redirect URL',
    ]
];

其他一些技巧

Scopes

在重定向用户之前,您还可以使用 scopes() 方法在请求上设置 “范围”。此方法将覆盖所有现有的作用域:

$response = $socialite->create('github')
                ->scopes(['scope1', 'scope2'])->redirect();

Redirect URL

你也可以动态设置' redirect_uri ',你可以使用以下方法来改变 redirect_uri URL:

$url = 'your callback url.';

$socialite->redirect($url);
// or
$socialite->withRedirectUrl($url)->redirect();

State

你的应用程序可以使用一个状态参数来确保响应属于同一个用户发起的请求,从而防止跨站请求伪造 (CSFR) 攻击。当恶意攻击者欺骗用户执行不需要的操作 (只有用户有权在受信任的 web 应用程序上执行) 时,就会发生 CSFR 攻击,所有操作都将在不涉及或警告用户的情况下完成。

这里有一个最简单的例子,说明了如何提供状态可以让你的应用程序更安全。在本例中,我们使用会话 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

查看更多关于 state 参数的文档

其他的一些参数

要在请求中包含任何可选参数,调用 with() 方法传入一个你想要设置的关联数组:

$response = $socialite->create('google')
                    ->with(['hd' => 'example.com'])->redirect();

User interface

标准的 user api:

$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"
  }
}

你可以像这样以数组键的形式获取 user 属性:

$user['id'];        // 1472352
$user['nickname'];  // "overtrue"
$user['name'];      // "安正超"
$user['email'];     // "[email protected]"
...

或者使用该 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();

从 OAuth API 响应中取得原始数据

$user->getRaw() 方法会返回一个 array

当你使用 userFromCode() 想要获取 token 响应的原始数据

$user->getTokenResponse() 方法会返回一个 array 里面是响应从获取 token 时候 API 返回的响应。

注意:当你使用 userFromCode() 时,这个方法只返回一个 有效的数组,否则将返回 null,因为 userFromToken() 没有 token 的 HTTP 响应。

通过 access token 获取用户信息

$accessToken = 'xxxxxxxxxxx';
$user = $socialite->userFromToken($accessToken);

Enjoy it! ❤️

参照

PHP 扩展包开发

想知道如何从零开始构建 PHP 扩展包?

请关注我的实战课程,我会在此课程中分享一些扩展开发经验 —— 《PHP 扩展包实战教程 - 从入门到发布》

License

MIT

socialite's People

Contributors

153264 avatar aa24615 avatar ac1982 avatar allowing avatar andares avatar anhao avatar aufree avatar bangbangda avatar chanxiaoxi avatar diegocardoso93 avatar doododo avatar expl0sif avatar forecho avatar her-cat avatar icebay avatar khrigo avatar khsing avatar kids-return avatar littlesqx avatar mingyoung avatar morphsteve avatar overtrue avatar phoenixgao avatar summerblue avatar thenorthmemory avatar thisliu avatar uptutu avatar wjfz avatar woei66 avatar yuqi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

socialite's Issues

微信没有获取unionid

对于微信开放平台下的所有公众号和APP应用,需要有union去识别唯一的用户,需要修改对应的代码

With request for Google contacts feed

I checked "Additional parameters" in the README and I have one question. How to add request for getting Google contacts? Can it be in the callback.php, like so:

$google = $socialite
	->driver('google')
	->scopes($scopes)
	->with(['contacts', 'https://www.google.com/m8/feeds/contacts/default/full?alt=json&max-results=400']);
$google->contacts;

Feed/scope based on tutorial: Mydnic.

AbstractProvider::getHttpClient() 每次调用都获取新的 Client 实例

相关代码如下:

/**
 * Get a fresh instance of the Guzzle HTTP client.
 *
 * @return \GuzzleHttp\Client
 */
protected function getHttpClient()
{
    return new Client(self::$guzzleOptions);
}

公司项目希望注入一个全局的并且自定义的 Client,但注释 (Get a fresh instance of the Guzzle HTTP client) 中提到获取一个 fresh 实例,即每次调用都获取一个新的实例,这样做有什么特别的用意吗?

Missing parameter: redirect_uri

Hi,
Im using your code inside my laravel 5.5 project, but i get error

Authorize Failed: {"error":"invalid_request","error_description":"Missing parameter: redirect_uri"}
in …\vendor\overtrue\socialite\src\Providers\AbstractProvider.php439

when i try to execute

$user = Socialite::driver('google')->user();

does google update their API? what can i do to pass redirect_uri?

你好,我想在电脑端用微信扫码登录,根据你的说明感觉是wechat_open,但提示无法驱动?

你好,我想在电脑端用微信扫码登录,根据你的说明感觉是wechat_open,但提示无法驱动?

错误信息如下:
Driver [wechat_open] not supported.

我同时使用了微信授权登录和QQ授权登录,都可以正常使用。

——————————————————————————————————————
然后我又看你写了如下说明,我就试着用scopes(['snsapi_login'])方式,但是报redirect_uri 参数错误

WeChat scopes:
snsapi_base, snsapi_userinfo - Used to Media Platform Authentication.
snsapi_login - Used to web Authentication.

$response = $socialite->driver('wechat')->scopes(['snsapi_login'])->redirect();

关于SocialiteManager::setRequest

在这个 RP 中 #63, 被你说的我都怀疑我自己了。

$options = [
    'github' => [
        'client_id' => 123,
        'client_secret' => '234'
    ]
];
$request = new Request(); // or use AnotherCustomRequest.

$socialite = new SocialiteManager($options);
$socialite->setRequest($request);
//SocialiteManager::__cal("setRequest", [])
//L254: SocialiteManager::driver(null)
//L114: SocialiteManager::getDefaultDriver()
//throw new InvalidArgumentException('No Socialite driver was specified.');

另外有一点, 最开始误解了 __call() 的意思,我以为 __call() 方法是这么用的:

$socialite = new SocialiteManager($options);
$socialite->github();  // 同 $socialite->driver('github')

看来我想错了。

getDefaultDriver 都是抛出异常的,__call() 方法有什么意义呢?用来别人写继承?

class MySocialiteManager extends SocialiteManager {
  public function getDefaultDriver() {
    return 'github';
  }
}

在 Windows Server 2016 IIS + PHP7 环境下使用overtrue/wechat包时,本关联包的问题。

在 Windows Server 2016 IIS + PHP7 环境下使用overtrue/wechat包时,发现本关联包中有个问题。

在使用微信网页授权回调时,取不到微信用户信息。排查异常信息发现如下异常:

[handlerContext:GuzzleHttp\Exception\RequestException:private] => Array
        (
            [errno] => 60
            [error] => SSL certificate problem: unable to get local issuer certificate
            [url] => https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxx&secret=xxxxxxx&grant_type=authorization_code
            [content_type] => 
            [http_code] => 0
            [header_size] => 0
            [request_size] => 0
            [filetime] => -1
            [ssl_verify_result] => 20
            [redirect_count] => 0
            [total_time] => 0.079
            [namelookup_time] => 0.016
            [connect_time] => 0.047
            [pretransfer_time] => 0
            [size_upload] => 0
            [size_download] => 0
            [speed_download] => 0
            [speed_upload] => 0
            [download_content_length] => -1
            [upload_content_length] => -1
            [starttransfer_time] => 0
            [redirect_time] => 0
            [redirect_url] => 
            [primary_ip] => 140.207.119.12
            [certinfo] => Array
                (
                )

            [primary_port] => 443
            [local_ip] => xxx.xxx.xxx.xxx
            [local_port] => 56291
        )

很明显是因为https证书问题导致。排查overtrue/wechat包时查到本关联包中文件

src/Providers/AbstractProvider.php

第462行

return new Client(['http_errors' => false]);

使用GuzzleHttp\Client时并没有加入

'verify' => false

初步断定为该问题导致。于是将代码修改为:

return new Client(['http_errors' => false,'verify' => false]);

然后再进行测试就能正常获取到微信用户信息。

我后来查看本包的代码库时发现最新的master分支代码已经对本问题做了修改,请问能否把

"require": {
    "overtrue/wechat": "^3.3"
  }

关联包的版本更新到最新的?

能否为AbstractProvider提供一个getRequest方法

我在使用您的EASYWECHAT项目,您在oauth中使用了原生的session驱动,我需要将它改为redis驱动,但是由于easywechat容器中的oauth对象是一个wechatProvider而不是socialite,使得我没法更改session驱动

关于微博用户拒绝授权

通过socialite跳转至微博授权页,页面提示用户登录微博,此时用户点击【取消】,微博会跳转至程序的callback页

继而GuzzleHttp抛出ClientException异常:

Client error: `POST https://api.weibo.com/2/oauth2/access_token` resulted in a `400 Bad Request` response:
{"error":"invalid_grant","error_code":21325,"request":"/2/oauth2/access_token","error_uri":"/2/oauth2/access_token","err

跳转callback:
foo.com/weibo/callback?error_uri=%2Foauth2%2Fauthorize&error=access_denied&error_description=user%20denied%20your%20request.&error_code=21330&state=8708586829ca1134ced0f754b00c2cd15c03157e

两处的error_code分别为
invalid_grant 21325 提供的Access Grant是无效的、过期的或已撤销的
access_denied 21330 用户或授权服务器拒绝授予数据访问权限

Thx.

我想问问facebook回调的时候报错time out 443

可以使用facebook登录。但是最后回调的时候显示这个

cURL error 7: Failed to connect to graph.facebook.com port 443: Timed out (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

百度谷歌无果,求大神支招

InvalidStateException at refresh with Google driver

When I refresh the page I get: Uncaught exception 'Overtrue\Socialite\InvalidStateException'. Is it possible to fix that behaviour? I also saw stateless = false at Laravel/Socialite.

The exception is being thrown when I call: $google->user();.

QQprovider里的getUserByToken方法第一个response存在错误

新版的QQprovider里134行 请求openid的时候新加入了一个unionid=1的参数,就是因为这个原因,后续的openid没法获取到 导致没法获取到用户信息
image
上面是加了&unionid的结果
image
这个是不加

劳烦大大看看是什么原因? 还有新版加入这个是为了什么呢?

Uncaught Overtrue\Socialite\InvalidStateException

write $user = $socialite->driver('github')->user();

and displays an error

Fatal error: Uncaught Overtrue\Socialite\InvalidStateException in C:\OSPanel\domains\oauth\vendor\overtrue\socialite\src\Providers\AbstractProvider.php:189 Stack trace: #0 C:\OSPanel\domains\oauth\index.php(21): Overtrue\Socialite\Providers\AbstractProvider->user() #1 {main} thrown in C:\OSPanel\domains\oauth\vendor\overtrue\socialite\src\Providers\AbstractProvider.php on line 189

使用access_token返回missing openid的错误

请问是不是要另外指定openid? 应用场景是app获取到token后 传递到服务器,服务器通过这个token获取用户的其他信息进行校验
代码部分:

        $socialite = new SocialiteManager($this->config);
        $accessToken = new AccessToken(['access_token' => $token]);
        $user = $socialite->driver('wechat')->user($accessToken);

token是APP端立即获取到的 应该不存在过期问题

symfony 的错误,不知道在这里说是不是合适

是这样,symfony/http-foundation/Session/Storage/NativeSessionStorage.php 的 106 行如下:

session_cache_limiter('')

这句对session做了一些操作。

我的逻辑,是判断用户是不是登陆,没登录就调用 easyWechat->getAuthUrl ,然后跳转到授权链接。

之前代码是没问题的, 能跑。

不过我刚升级了php 7.2.2,就跳出了一个错误

php session_cache_limiter(): Cannot change cache limiter when session is active

我研究了下,大概新版本的php中, session_cache_limiter 必须放在session_start前面。然而我又需要session 去判断是否登陆。

死循环了,求新有有风险。

不知道有没有人遇到这个情况,有解决方案说一下,谢谢。否则我只能回退到老版本了。。

Config class set方法问题

当我调用Config->set方法的时候,会出现原config 被覆盖的情况

               $config = [
			'a' => 'test1',
			'b' => [
				'c' =>'test2'
			]
		];

		$c = new Config($config);
		print_r($c->get(null));

		$c->set("d.e.f","test3");
		print_r($c->get(null));

然后 上列输出分别是

Array
(
    [a] => test1
    [b] => Array
        (
            [c] => test2
        )

)
Array
(
    [f] => test3
)

我不知道这个是否算是问题,还是特意设计的

'SocialiteManager'中的创建默认的Session类不支持put方法

    /**
     * Create default request instance.
     *
     * @return \Symfony\Component\HttpFoundation\Request
     */
    protected function createDefaultRequest()
    {
        $request = Request::createFromGlobals();
        $session = new Session();

        $request->setSession($session);

        return $request;
    }
    public function redirect($redirectUrl = null)
    {
        $state = null;

        if (!is_null($redirectUrl)) {
            $this->redirectUrl = $redirectUrl;
        }

        if ($this->usesState()) {
            $state = sha1(uniqid(mt_rand(1, 1000000), true));
            $this->request->getSession()->put('state', $state);
        }

        return new RedirectResponse($this->getAuthUrl($state));
    }
  • 上面的Session类好像不支持put方法;这样就会导致报错了;
\Symfony\Component\HttpFoundation\Session\Session
  • 上面的问题只有在初始化SocialiteManager时,没有设置request时产生,例如:
    new SocialiteManager($config);
  • 但是不知道为什么前几天调试的时候都没有问题,就今天发生了;不知是不是我哪里配置有问题?或者还是其他什么问题?

微信Oauth 认证state默认关闭存在CSRF

超哥好。不知道是不是我没找着调用方式

protected function makeState()

我发现 makeState这个方法,在\Socialite\Providers\WeChatProvider中它是默认关闭的,我理解的是stateless属性为true,它将不会在授权构造请求query时候构造有效的state属性

public function redirect($redirectUrl = null)
它在这里判断

protected $stateless = true;

我理解的是在微信Oauth中如果没有state检查将会存在CSRF漏洞,OAuth CSRF配合XSS、任意URL跳转漏洞或者图片文件地址未限制。所以当时这个是有什么其他原因将其关闭吗,我可以扩展一下吗,我想通过use Symfony\Component\Cache\Simple\RedisCache 这个类,类似缓存access_token的方式,做一个验证,在回调URL授权种cookie前,先检查state参数是否为之前生成的随机数。如果不是,返回授权错误。

更多参考:

  1. OAuth 安全指南 http://static.hx99.net/static/drops/papers-1989.html
  2. OAuth 2.0安全案例回顾 http://static.hx99.net/static/drops/papers-598.html

进行第三方登陆,有时候可以正常登录有时候就报错

我换其他帐号也是一样 微博也是,
但是清除一下cookie 后就可以正常了,然后qq正常后 微博也正常了,只要其中一个不正常那么 两个都是不正常的,
我测试了一下 IE正常 EDGE不报错但是 没登录成功 这是什么问题啊?
php 代码

/**
 * QQ登录
 */
public function qqLogin(){
    $this->otherLogin('qq',1);
    return redirect('/');
}

/**
 * 第三方登录
 * @param unknown $name 第三方登录名称
 * @param unknown $type 登录类型 1QQ 2微博
 * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
 */
public function otherLogin($name, $type){
    $socialite = new SocialiteManager(config('services'));
    $clientUser = $socialite->driver($name)->user();
    $user = User::where('account',$clientUser->getId())->first();
    if (!$user){
        $user = User::create([
                'account' => $clientUser->getId(),
                'password' => bcrypt(str_random(16)),
                'name' => $clientUser->getNickname(),
                'login_type' => $type,
                'avatar' => $clientUser->getAvatar(),
        ]);
    }
    \Auth::login($user);
}

报错

Whoops, looks like something went wrong.
1/1 InvalidStateException in AbstractProvider.php line 170:

in AbstractProvider.php line 170
at AbstractProvider->user() in LoginController.php line 56
at LoginController->otherLogin('qq', '1') in LoginController.php line 36
at LoginController->qqLogin()
at call_user_func_array(array(object(LoginController), 'qqLogin'), array()) in Controller.php line 80
at Controller->callAction('qqLogin', array()) in ControllerDispatcher.php line 146
at ControllerDispatcher->call(object(LoginController), object(Route), 'qqLogin') in ControllerDispatcher.php line 94
at ControllerDispatcher->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in ControllerDispatcher.php line 96
at ControllerDispatcher->callWithinStack(object(LoginController), object(Route), object(Request), 'qqLogin') in ControllerDispatcher.php line 54
at ControllerDispatcher->dispatch(object(Route), object(Request), 'App\Http\Controllers\Home\LoginController', 'qqLogin') in Route.php line 174
at Route->runController(object(Request)) in Route.php line 140
at Route->run(object(Request)) in Router.php line 724
at Router->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in VerifyCsrfToken.php line 64
at VerifyCsrfToken->handle(object(Request), object(Closure))
at call_user_func_array(array(object(VerifyCsrfToken), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ShareErrorsFromSession.php line 49
at ShareErrorsFromSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(ShareErrorsFromSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64
at StartSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(StartSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure))
at call_user_func_array(array(object(AddQueuedCookiesToResponse), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59
at EncryptCookies->handle(object(Request), object(Closure))
at call_user_func_array(array(object(EncryptCookies), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Router.php line 726
at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 699
at Router->dispatchToRoute(object(Request)) in Router.php line 675
at Router->dispatch(object(Request)) in Kernel.php line 246
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Debugbar.php line 51
at Debugbar->handle(object(Request), object(Closure))
at call_user_func_array(array(object(Debugbar), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 44
at CheckForMaintenanceMode->handle(object(Request), object(Closure))
at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Kernel.php line 132
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 99
at Kernel->handle(object(Request)) in index.php line 58

request add param

Socialite::driver('facebok')
->with(['hd' => 'example.com'])
->redirect();

the answer in the handle does not have my parameter appended?

FacebookProvider: AuthorizeFailedException thrown due to response parse error.

Hi,

I'm trying to use this package with Facebook oauth, but the access token response is not being parsed correctly:

( ! ) Fatal error: Uncaught exception 'Overtrue\Socialite\AuthorizeFailedException' with message 'Authorize Failed: {"{"access_token":"REMOVED","token_type":"bearer","expires_in":5182660}":""}' in PROJECT/vendor/overtrue/socialite/src/Providers/AbstractProvider.php on line 400
( ! ) Overtrue\Socialite\AuthorizeFailedException: Authorize Failed: {"{"access_token":"REMOVED","token_type":"bearer","expires_in":5182660}":""} in PROJECT/vendor/overtrue/socialite/src/Providers/AbstractProvider.php on line 400

Call Stack
# Time Memory Function Location
1 0.0001 242856 {main}( ) .../index.php:0
2 0.0025 506752 require_once( 'PROJECT/scripts/account.php' ) .../index.php:38
3 0.0025 507040 ACCOUNT->login_social_callback( ) .../account.php:42
4 0.0044 728120 Overtrue\Socialite\Providers\AbstractProvider->user( ) .../account.php:699
5 0.0045 729472 Overtrue\Socialite\Providers\FacebookProvider->getAccessToken( ) .../AbstractProvider.php:173
6 0.4131 969080 Overtrue\Socialite\Providers\FacebookProvider->parseAccessToken( ) .../FacebookProvider.php:89
7 0.4131 969832 Overtrue\Socialite\Providers\AbstractProvider->parseAccessToken( )

The problem code in FacebookProvider.php:

    /**
     * Get the access token for the given code.
     *
     * @param string $code
     *
     * @return \Overtrue\Socialite\AccessToken
     */
    public function getAccessToken($code)
    {
        $response = $this->getHttpClient()->get($this->getTokenUrl(), [
            'query' => $this->getTokenFields($code),
        ]);

        return $this->parseAccessToken($response->getBody());
    }

    /**
     * {@inheritdoc}
     */
    protected function parseAccessToken($body)
    {
        parse_str($body, $token);

        return parent::parseAccessToken($token);
    }

This causes the whole response body to be incorrectly parsed into a array with the key being the json text, and the value being null.

To correct the issue I just removed the methods from FacebookProvider.php and let it use the AbstractProvider methods, which seems to work fine.

Perhaps this is a change in the response that Facebook are now sending? I'm using OG v2.9 in my app.

EDIT: My full versions:

➤ composer info
abraham/twitteroauth      0.7.2  The most popular PHP library for use with the Twitter OAuth REST API.
codegun/phpmailer-lite    1.0.0  PHPMailerLite By PHPMailer
guzzlehttp/guzzle         6.2.3  Guzzle is a PHP HTTP client library
guzzlehttp/promises       v1.3.1 Guzzle promises library
guzzlehttp/psr7           1.4.2  PSR-7 message implementation that also provides common utility methods
overtrue/socialite        1.0.25 A collection of OAuth 2 packages that extracts from laravel/socialite.
phpoffice/phpexcel        1.8.1  PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine
psr/http-message          1.0.1  Common interface for HTTP messages
symfony/http-foundation   v3.2.8 Symfony HttpFoundation Component
symfony/polyfill-mbstring v1.3.0 Symfony polyfill for the Mbstring extension
➤ php -v
PHP 7.1.5 (cli) (built: May 13 2017 13:28:23) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Xdebug v2.5.4, Copyright (c) 2002-2017, by Derick Rethans

配置your-component-access-token应该填什么呢?

'wechat_open' => [
    'client_id'     => 'your-app-id',
    'client_secret' => ['your-component-appid', 'your-component-access-token'],
    'redirect'      => 'http://localhost/socialite/callback.php',
]

找了微信开放平台和微信公众平台都没发现相关参数,your-component-access-token 应该填哪里的参数呢?

Wechat login not available?

image

Well, finally I found out I am using official account app Id and secret but it required wechat open app Id and secret.

如何只输出登录链接,不要直接跳转到授权登录页面

`$socialite = new SocialiteManager($facebook_config);
$response = $socialite->driver('facebook')->redirect();

echo $response;// or $response->send();`

如何只输出登录链接,不要直接跳转到授权登录页面,我们登录页面同时有好几种登录方式让用户选择

$this->attributes 如果为null,则会报出异常

AttributeTrait.php 
/**
     * Map the given array onto the user's properties.
     *
     * @param array $attributes
     *
     * @return $this
     */
    public function merge(array $attributes)
    {
      
        $this->attributes = array_merge($this->attributes, $attributes);

        return $this;
    }

WechatProvider 能提供一个根据getAccessToken($code),根据access_token,openid实例化返回的AccessToken对象

/**
     * Detect wechat open platform.
     *
     * @param $code
     * @return AccessToken new AccessToken(['access_token'=>$access_token,'openid'=>$openid]);
     * @throws AuthorizeFailedException
     */
    public function getAccessTokenNew($code)
    {
        $response = $this->getHttpClient()->get($this->getTokenUrl(), [
            'query' => $this->getTokenFields($code),
        ]);
        $body = $response->getBody();
        if (!is_array($body)) {
            $body = json_decode($body, true);
        }

        if (empty($body['access_token'])) {
            throw new AuthorizeFailedException('Authorize Failed: '.json_encode($body, JSON_UNESCAPED_UNICODE), $body);
        }
        return new AccessToken(['access_token'=>$body['access_token'],'openid'=>$body['openid']]);
    }

因为我只想通过$code获取access_token,并获取用户信息,但是现在提供的getAccessToken函数返回的是只根据access_token实例化的对象,然后再调用获取user信息的时候就保openid为空啦,我使用的方式如下:

$socialite = new SocialiteManager(Yii::$app->params['wxconfig']);
$accessToken = $socialite->driver('wechat')->getAccessToken($code); 
$user = $socialite->driver('wechat')->user($accessToken);  //现在代码执行到这里的时候报openid必须输入

Google stop working, Invalid_Grant

Hi!
This Library was working great for me, until google send me an error:

Fatal error: Uncaught Overtrue\Socialite\AuthorizeFailedException: Authorize Failed: {"error":"invalid_grant","error_description":"Code was already redeemed."} in /home/sizeme/htdocs/vendor/overtrue/socialite/src/Providers/AbstractProvider.php:418 Stack trace: #0 /home/sizeme/htdocs/vendor/overtrue/socialite/src/Providers/GoogleProvider.php(75): Overtrue\Socialite\Providers\AbstractProvider->parseAccessToken(Array) #1 /home/sizeme/htdocs/vendor/overtrue/socialite/src/Providers/AbstractProvider.php(180): Overtrue\Socialite\Providers\GoogleProvider->getAccessToken('4') #2 /home/sizeme/htdocs/app/Controller/account.php(227): Overtrue\Socialite\Providers\AbstractProvider->user() #3 [internal function]: Controller\accountController->authorize() #4 /home/sizeme/htdocs/vendor/dframe/dframe/src/Router.php(90): call_user_func_array(Array, Array) #5 /home/sizeme/htdocs/vendor/dframe/dframe/src/Core.php(17): Dframe\Router->run() #6 /home/sizeme/htdocs/web/index.php(14): Dframe\Core->run() #7 {main} thrown in /home/sizeme/htdocs/vendor/overtrue/socialite/src/Providers/AbstractProvider.php on line 418`

I don't know if I make a mistake.
Any solutions?

@edit
Sorry my framework mistake...

有没有哪个方法直接通过access_token获取用户信息?

因为是在app上做第三方登录,比如用友盟的qq登录,登录成功后已经获取到了uid和access_token,我想把uid和access_token传回到服务器进行验证和获取信息。
有没有哪个方法直接通过access_token获取用户信息?

能更新下文档吗?

callback.php:

`<?php

// ...
$user = $socialite->driver('github')->user();

$user->getId(); // 1472352
$user->getNickname(); // "overtrue"
$user->getUsername(); // "overtrue"
$user->getName(); // "安正超"
$user->getEmail(); // "[email protected]"
$user->getProviderName(); // GitHub
...`

能不能把第一个省略号去掉,我被这个坑了一天,就写完整,我保证肯定不只一个人像我这样,以为是存session

`<?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);
$user = $socialite->driver('github')->user();

$user->getId(); // 1472352
$user->getNickname(); // "overtrue"
$user->getUsername(); // "overtrue"
$user->getName(); // "安正超"
$user->getEmail(); // "[email protected]"
$user->getProviderName(); // GitHub
...`

如何自定义登录时的scope?

因为应用场景不同,可能希望拿到一些别的数据,比如repo信息。我查了下api 文档,似乎和跳转时的 scope有关

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.