【问题标题】:Successful GitHub OAuth doesn't redirect via Location header成功的 GitHub OAuth 不会通过 Location 标头重定向
【发布时间】:2014-12-28 04:31:17
【问题描述】:

我正在使用PHPoAuthLib 和 GitHub 为我的 PHP Web 应用程序提供一个简单的 OAuth 登录系统。我复制了the example,但遇到了一个问题:浏览器不处理来自 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)。

This question 听起来很相似,但是在这种情况下有效的解决方案在我的情况下不起作用(而且我看不出它会有什么不同:作者建议 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 上尝试了相同的操作,它运行良好。所以它要么是浏览器问题(或者 Midori 很乐意重定向,尽管在重定向回复中收到了 HTML 内容)。

【问题讨论】:

    标签: php oauth-2.0 github-api


    【解决方案1】:

    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';
    }
    

    【讨论】:

    • 在我的附录中,我指出我也尝试了一个真实的域,并且遇到了同样的问题。无论如何,为什么仅限本地域会造成问题?它需要在开发机器上工作。感谢您的链接,虽然它似乎没有显示任何代码,我不会授权任何我不信任的应用程序:-)
    • @halfer 您是否在服务器上尝试过您的代码? Github 不知道要重定向哪个 url(互联网上不存在 url)。
    • 这只是一个 HTTP 重定向,不是吗?如果是这样,当收到Location: 标头时,是我的浏览器执行重定向,并且它知道如何重定向到我给它的域。无论如何,如果我的wget 测试表明我的应用程序中真正发生了什么,那么问题就出现在 GH 页面上,在处理重定向之前。
    • 我已更新问题以表明我的本地域确实解析为本地 IP 地址。无论如何,我认为这不是问题所在,因为真实域的行为方式也相同。
    • 我没有收到关于您的更新的通知,但谢谢您(一般来说,最好添加评论)。我不想在生产中使用此代码,因为它会将我绑定到 GitHub - 我明确使用了 PHPoAuthLib,因此我可以为我的用户提供各种 SSO 提供程序。也就是说,这可能有助于调试问题 - PHPoAuthLib 生成的 URL 比您的示例具有更多参数。我会告诉你我的进展情况!
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-02-12
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 2016-09-29
      • 2016-09-28
      • 1970-01-01
      相关资源
      最近更新 更多