Laravel的Guzzle和Form + Basic Auth问题

时间:2016-12-28 15:45:59

标签: php authentication oauth laravel-5.3 guzzle

我一直在研究从Livecoding.tv中获取一些数据,我目前正在重复使用我用于twitch API的Oauth2控制器,这应该非常简单。

如果有人不知道,Oauth使用的流程如下:

  1. 使用您的应用代码将用户重定向到第三方Oauth链接。

  2. 用户授权。

  3. 用户再次使用授权令牌重定向到您的网站,然后您可以发送给第三方以获取刷新令牌等。

  4. 现在在第3步,我遇到了一些问题。以下是开发人员的描述和示例:

    获取令牌:https://www.livecoding.tv/o/token/

    标题

    HTTP Basic身份验证,使用application_code作为用户名,application_secret作为密码,如下例所示。

    POST Body

    code=EXAMPLE Token gotten from redirect
    grant_type=Your grant type (authorization_type)
    redirect_uri=Your redirect URL
    

    以下是来自工作卷曲请求文档的示例cURL请求。

    curl -X POST -d "grant_type=authorization_code&code=Php4iJpXGpDT8lCqgBcbfQ2yzhB0Av&client_id=vCk6rNsC&redirect_uri=http://localhost/externalapp" -u"vCk6rNsC:sfMxcHUuNnZ" https://www.livecoding.tv/o/token/
    

    所以我试图在Postman(https://www.getpostman.com/)中创建这个,开箱即用,然后我要求Postman将其转换为PHP,看看我是否错过了什么。以下是邮递员工作要求的结果:

    <?php
    
    $curl = curl_init();
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => "https://www.livecoding.tv/o/token/",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_POSTFIELDS => "code=SOMECODE&client_id=SOMECLIENTID&redirect_uri=SOMEURL&grant_type=authorization_code",
      CURLOPT_HTTPHEADER => array(
        "authorization: Basic U09NRVVTRVI6U09NRVBBU1NXT1JE",
        "cache-control: no-cache",
        "content-type: application/x-www-form-urlencoded",
        "postman-token: c8df4bbc-cbd0-73eb-df35-80210989db33"
      ),
    ));
    
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    curl_close($curl);
    
    if ($err) {
      echo "cURL Error #:" . $err;
    } else {
      echo $response;
    }
    

    我很高兴这马上得到了解决,所以我只需要让一个Guzzle客户端做同样的事情,这已经适用于Twitch Oauth,这是我的代码:

    {
                $providers = ServiceProvider::findOrFail(2);
                $client = new Client([
                    'base_uri' => $providers->oauth_url . '/token/',
                    'form_params' => [
                        'code' => $token,
                        'grant_type' => 'authorization_code',
                        'client_id' => $providers->application_code,
                        'redirect_uri' => $providers->redirection_url
                    ],
                    'auth' => [
                        'somestring',
                        'someotherstring',
                    ],
                    'headers' => [
                        'Content type' => 'application/x-www-form-urlencoded',
                        'cache-control' => 'no-cache'
                    ]
                ]);
                $response = $client->request('POST');
                return ($response);
            }
    

    这只会让我回复401,所以我决定做一些调试,如果我在发送之前就停止了请求:

    Client {#637 ▼
      -config: array:10 [▼
        "base_uri" => Uri {#676 ▼
          -scheme: "https"
          -userInfo: ""
          -host: "www.livecoding.tv"
          -port: null
          -path: "/o/token/"
          -query: ""
          -fragment: ""
        }
        "form_params" => array:4 [▼
          "code" => "SOMECODE"
          "grant_type" => "authorization_code"
          "client_id" => "SOMECLIENTID"
          "redirect_uri" => "http://REDIRECTURI"
        ]
        "auth" => array:2 [▼
          0 => "SOMECLIENTID"
          1 => "SOMECLIENTSECRET"
        ]
        "headers" => array:3 [▼
          "Content type" => "application/x-www-form-urlencoded"
          "cache-control" => "no-cache"
          "User-Agent" => "GuzzleHttp/6.2.1 curl/7.26.0 PHP/5.6.27-1~dotdeb+7.1"
        ]
        "handler" => HandlerStack {#664 ▼
          -handler: Closure {#671 ▼
            class: "GuzzleHttp\Handler\Proxy"
            parameters: {▼
              $request: {▼
                typeHint: "Psr\Http\Message\RequestInterface"
              }
              $options: {▼
                typeHint: "array"
              }
            }
            use: {▼
              $default: Closure {#669 ▼
                class: "GuzzleHttp\Handler\Proxy"
                parameters: {▼
                  $request: {▼
                    typeHint: "Psr\Http\Message\RequestInterface"
                  }
                  $options: {▼
                    typeHint: "array"
                  }
                }
                use: {▼
                  $default: CurlMultiHandler {#634 ▼
                    -factory: CurlFactory {#667 ▼
                      -handles: []
                      -maxHandles: 50
                    }
                    -selectTimeout: 1
                    -active: null
                    -handles: []
                    -delays: []
                  }
                  $sync: CurlHandler {#666 ▼
                    -factory: CurlFactory {#665 ▼
                      -handles: []
                      -maxHandles: 3
                    }
                  }
                }
                file: "/LARAVELPATH/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php"
                line: "25 to 29"
              }
              $streaming: StreamHandler {#670 ▼
                -lastHeaders: []
              }
            }
            file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php"
            line: "49 to 53"
          }
          -stack: array:4 [▼
            0 => array:2 [▼
              0 => Closure {#672 ▼
                class: "GuzzleHttp\Middleware"
                parameters: {▶}
                file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
                line: "54 to 69"
              }
              1 => "http_errors"
            ]
            1 => array:2 [▼
              0 => Closure {#673 ▼
                class: "GuzzleHttp\Middleware"
                parameters: {▶}
                file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
                line: "148 to 150"
              }
              1 => "allow_redirects"
            ]
            2 => array:2 [▼
              0 => Closure {#674 ▼
                class: "GuzzleHttp\Middleware"
                parameters: {▶}
                file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
                line: "27 to 43"
              }
              1 => "cookies"
            ]
            3 => array:2 [▼
              0 => Closure {#675 ▼
                class: "GuzzleHttp\Middleware"
                parameters: {▶}
                file: "LARAVELPATH/vendor/guzzlehttp/guzzle/src/Middleware.php"
                line: "216 to 218"
              }
              1 => "prepare_body"
            ]
          ]
          -cached: null
        }
        "allow_redirects" => array:5 [▼
          "max" => 5
          "protocols" => array:2 [▼
            0 => "http"
            1 => "https"
          ]
          "strict" => false
          "referer" => false
          "track_redirects" => false
        ]
        "http_errors" => true
        "decode_content" => true
        "verify" => true
        "cookies" => false
      ]
    }
    

    正如您在此处所看到的,此处只有一个名为“auth”的参数,而不是Guzzle中记录的基本身份验证:http://docs.guzzlephp.org/en/latest/request-options.html#auth

    虽然我会提到输入正确的值。

    对于调试我刚做dd($client),我不知道这是否会给我所有答案?

    所以另一种可能性就是对它进行base64编码(就像它在一般的基本身份验证中一样),然后手动添加“授权”标题,我试过了,但我不知道我是否正确地做了:

    $credentials = base64_encode($clientvariable . ':' . $clientsecretvariable)
    

    这是正确的方法吗?虽然如果我没有让guh参数在Guzzle中工作,我宁愿使用它作为最后的手段。

    我知道关于Guzzle和基本身份验证的其他Stackoverflow问题,是的,我已经阅读过它们,希望我已经提供了足够的信息来表明这一点。

1 个答案:

答案 0 :(得分:0)

这里的问题与我如何从Guzzle返回响应有关。

由于我刚刚返回$ response,这只是流,浏览器从未返回任何内容,并且自从Chrome自动刷新后,他运行请求两次,第二次,我只需要两次代码,会发生错误。

我最终对此疯狂,直到我改变了浏览器,发现没有发生任何事情,这使我指向了正确的方向。