成功的 GitHub OAuth 不会通过位置标头重定向


Successful GitHub OAuth doesn't redirect via Location header

我正在使用PHPoAuthLib和GitHub为我的PHP Web应用程序提供一个简单的OAuth登录系统。我已经复制了该示例,但遇到了一个问题:浏览器未处理来自 GitHub 的重定向。

我的应用成功重定向到 GitHub 授权页面,如下所示:

https://github.com/login/oauth/authorize?type=web_server&client_id=516xxx7dd9fda3113ef&redirect_uri=http%3A%2F%2Fawooga.local%2Fauth&response_type=code&scope=user%3Aemail

GitHub 生成一个页面,然后在大量标头中,该页面包括以下内容:

Location: http://awooga.local/auth?code=5fb910f67xxxxx91003

但是,浏览器不会处理此问题。起初我认为这是 Slim 框架中的一个问题,我也在使用这个框架。因此,我将其删除,问题仍然存在。然后我尝试在 GitHub URL 上wget,发现 GitHub 生成了一个错误页面,其中包括这个非常普遍的错误:

<div id="ajax-error-message" class="flash flash-error">
  <span class="octicon octicon-alert"></span>
  <a href="#" class="octicon octicon-x flash-close js-ajax-error-dismiss" aria-label="Dismiss error"></a>
  Something went wrong with that request. Please try again.
</div>

这可以解释为什么它在浏览器中不起作用 - 如果已发送HTML,则无法进行Location重定向。但是,奇怪的是,如果我获取重定向 URL 并将其手动粘贴到我的浏览器中,则表明身份验证实际上已经起作用。因此,据我所知,GitHub没有理由抱怨问题。

(如果不清楚,http://awooga.local域在我的机器上工作正常 - 它在本地 DNS 中设置为指向127.0.0.1 (。

这个问题听起来很相似,但在这种情况下有效的解决方案在我的问题上不起作用(我看不出它会有什么区别:作者建议 GH 登录 URL 应该是应用程序中的直接链接,而不是重定向(。


后记1:我想知道GH是否可能发现仅本地域有问题。为了验证这个理论,我在/etc/hosts中用一个127.0.0.1条目覆盖了一个真实的域,交换了凭据,以便它们与GH上注册的应用程序匹配,然后重试。我得到完全相同的行为:重定向被接收但未执行。我假设正在发生的事情是之前通过wget揭示的内容 - HTML 响应中的非特定错误正在阻止重定向运行。


后记2:我已经排除了OAuth库。我使用了下面答案的变体来使用 PHP 中的原始 cURL 操作,其操作与上述相同 - Location 标头受阻可能是因为 GH 在 HTML 响应中报告了非特定问题。由于我使用指向 GH /login/oauth/authorize端点的直接 URL,因此我看不到可能出现的问题。然后,我从响应中找出位置,将其粘贴到我的浏览器中,它工作正常 - 它从 GitHub 获取访问令牌,然后可用于运行用户调用。我的所有用户信息都已成功获取。

我正在从 Firefox 添加一些请求/响应标头,以防它有助于阐明问题:

https://github.com/login/oauth/authorize?client_id=xxx&redirect_uri=http://awooga.local/auth2.php

请求:

Host:"github.com"
User-Agent:"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0"
Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Accept-Language:"en-gb,en;q=0.5"
Accept-Encoding:"gzip, deflate"
Referer:"http://awooga.local/auth"
Cookie:"logged_in=yes; <stripped for security>"
DNT:"1"
Connection:"keep-alive"

响应:

Cache-Control:"no-cache, private"
Content-Type:"text/html; charset=utf-8"
Date:"Sat, 27 Dec 2014 19:31:59 GMT"
Location:"http://awooga.local/auth2.php?code=zzz"
Server:"GitHub.com"
Set-Cookie:"user_session=aaa; path=/; expires=Sat, 10-Jan-2015 19:31:59 GMT; secure; HttpOnly
_gh_sess=??; path=/; secure; HttpOnly"
Status:"302 Found"
Strict-Transport-Security:"max-age=31536000; includeSubdomains; preload"
Transfer-Encoding:"chunked"
Vary:"X-PJAX, Accept-Encoding"
X-Content-Type-Options:"nosniff"
X-Frame-Options:"deny"
X-GitHub-Request-Id:"(stripped)"
X-GitHub-Session-Id:"(stripped)"
X-GitHub-User:"halfer"
X-Rack-Cache:"miss"
X-Request-Id:"(stripped)"
X-Runtime:"0.016812"
X-Served-By:"(stripped)"
X-XSS-Protection:"1; mode=block"
content-security-policy:"default-src *; script-src assets-cdn.github.com collector-cdn.github.com; object-src assets-cdn.github.com; style-src 'self' 'unsafe-inline' 'unsafe-eval' assets-cdn.github.com; img-src 'self' data: assets-cdn.github.com identicons.github.com www.google-analytics.com collector.githubapp.com *.githubusercontent.com *.gravatar.com *.wp.com; media-src 'none'; frame-src 'self' render.githubusercontent.com gist.github.com www.youtube.com player.vimeo.com checkout.paypal.com; font-src assets-cdn.github.com; connect-src 'self' ghconduit.com:25035 live.github.com uploads.github.com www.google-analytics.com s3.amazonaws.com"
x-ua-compatible:"IE=Edge,chrome=1"

后脚本3:我已经在我的系统上的另一个浏览器Midori上尝试了相同的方法,它工作正常。所以这要么是浏览器问题(或者尽管在重定向回复中收到了 HTML 内容,但 Midori 很乐意重定向(。

http://awooga.local不是

real域。

在这里查看一个小例子:http://githubv3.herokuapp.com/

========更新

==

=======

对不起,那边的小姐;(

这是我编写的示例代码:

index.html

<html>
    <head>          
    </head>
    <body>
        hi,there
        <br>
        <!-- replace with your own client_id and redirect uri -->
        <a href="https://github.com/login/oauth/authorize?client_id=YourClientId&redirect_uri=http://www.sites.com/github/callback.php">github login</a>
    </body>
</html>

callback.php

<?php
if(isset($_GET['code'])){
    $code = $_GET['code'];
    // post to get access_token
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, true);
    // your own client_id and client_secret
    $url = "https://github.com/login/oauth/access_token?client_id=YourClientId&client_secret=YourClientSecret&code=$code";
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Accept: application/json'
        ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    if($result === false){
        echo 'curl error'.curl_error($ch);
    }else{
        $response = json_decode($result, true);
        $accessToken = $response['access_token'];
        if(!empty($accessToken)){
            $ch = curl_init();
            $url = "https://api.github.com/user?access_token=$accessToken";
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Accept: application/vnd.github.v3+json'
                ));
            curl_setopt($ch, CURLOPT_USERAGENT,  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.6 Safari/537.11");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $result = curl_exec($ch);
            if($result === false){
                echo 'curl error'.curl_error($ch);  
            }else{
                echo 'auth user info:<br>';
                var_dump($result);
            }
        }else{
            echo 'access_token empty';
        }
    }
    curl_close($ch);
}else{
    echo 'no code';
}

我已经修复了它,尽管我不完全确定出了什么问题。我尝试了Midori,然后单独安装了Firefox,两者都工作正常。因此,我在通常的Firefox安装中禁用了一些插件,并开始正确重定向。

奇怪的是,我重新启用了有问题的插件,现在无法让它再次失败。也许禁用和重新启用的过程以某种方式重置了它们?似乎是狐狸代理负责的,但由于我已经重新启用它而没有问题,我现在不太确定。