我正在使用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安装中禁用了一些插件,并开始正确重定向。
奇怪的是,我重新启用了有问题的插件,现在无法让它再次失败。也许禁用和重新启用的过程以某种方式重置了它们?似乎是狐狸代理负责的,但由于我已经重新启用它而没有问题,我现在不太确定。