OAuth 重定向后会话丢失
Posted
技术标签:
【中文标题】OAuth 重定向后会话丢失【英文标题】:Session is lost after an OAuth redirect 【发布时间】:2014-03-31 12:42:21 【问题描述】:我使用的是 Cakephp 2.4。我的网站上有一个OAuth signin。 %99.5 的登录成功,但 %0.5 失败。我有这个错误好几个月了。我尝试了很多东西来调试和记录,但我仍然没有解决问题。尽管大多数请求都很好,但我需要解决一小部分。
场景是这样的:
用户点击登录按钮 我从服务器获取请求令牌(例如 yahoo、twitter) 我在用户会话中保存oauth_token
例如会话 ID 是 aaa1234
CakePHP 创建 PHPSESSID cookie 并将会话 ID 保存在该 cookie 中。
我将用户重定向到 Twitter 服务器并且用户确认我的应用程序
用户使用 oauth 验证器访问我的网站 a) 我使用用户的oauth_token
和oauth_verifier
并得到access_tokens
。会话 ID 是 aaa1234
。一切都很好。
b) 失败。因为我在当前会话中找不到用户的oauth_token
。当我检查会话 ID 时,我看到 ID 已更改,现在 ID 为 bbb2345
对于场景 b:
似乎用户现在有新的会话 ID。在新会话中找不到oauth_token
。但请注意,旧会话数据存在于/tmp/sessions/
文件夹中。
会话 aaa1234
的会话 ID cookie 不存在。但是我 2 天前设置的另一个跟踪 cookie 存在于 cookie 中。
我检查用户代理。 用户第一次来,用户从雅虎服务器回来也是一样。
这种故障场景发生在Chrome、Firefox、移动浏览器或其他浏览器中,所以我无法指责浏览器类型。 我应该检查什么来诊断?
我的 CakePHP core.php 设置:
Configure::write('Session', array( 'defaults' => 'cake' ));
Configure::write('Session.cookie', 'MYPHPSESSID');
Configure::write('Session.timeout', 120);
Configure::write('Security.level', 'medium');
文件中提到的其他设置是默认设置: https://github.com/cakephp/cakephp/blob/2.5/app/Config/core.php#L182
编辑:通过使用this answer,我检查了cookie。 20% 的错误用户禁用了 cookie。我亲自询问并且用户确认了 cookie 选项。但似乎其他用户没有禁用 cookie。还有一些用户使用 android WebViews 访问我的网站。在 WebView 客户端中,我确定我没有禁用 cookie。 99%的WebView用户也能成功使用网站。
【问题讨论】:
看来您的会话 ID 没有正确传递回服务器。可能发生如果第一次设置会话 cookie 以响应立即重定向到其他地方的请求。 很抱歉我听不懂。如果会话 cookie 是第一次设置,那么它会做什么? 一个问题,您是通过 dialogPopUp 窗口还是普通窗口请求请求令牌? @AbdouTahiri 不是对话。我将用户重定向到 Yahoo 或 Twitter 授权页面,用户离开了我的网站。当用户授权他回到我的网站。 我的意思是雅虎登录页面出现在当前浏览器窗口或单独的弹出窗口中? 【参考方案1】:您的会话 ID 可能会因为方案之间的重定向而丢失。 如果您的用户在 HTTP 上收到会话 ID,然后在 HTTPS 上返回(反之亦然),他的会话将丢失/被他之前的旧会话替换在那个计划上。
这不是 100% 确定的,但如果我是你,我会尝试看看(在我过去的项目中也发生过这种情况)。
编辑 说明:
客户端在 HTTP 上获取他们的会话,为了 oauth 目的,他们被重定向,当他们回来时,他们通过 HTTPS 来。
在 HTTP 和 HTTPS 之间移动时,PHP 正常会话 ($_SESSION) 会丢失。会话本身保留在服务器端,但是客户端丢失了 session_id,因此服务器无法识别他并且会话丢失了,所以我使用的是纯 PHP,100% 的客户端会在途中丢失会话背部。
CakePHP 通过保存会话 id 的 cookie 来处理这个常见问题,然后当客户端返回请求标头上没有 session_id 时,由于 cookie 会恢复其会话。 0.05% 的失败客户是具有以下一项(或多项)的客户:
-
禁用 Cookie(更常见)
在 HTTP/HTTPS 之间切换时不保留来自同一网站的 cookie 的浏览器(非常少见)
可能的解决方案:
首先在 HTTPS 上初始化 cookie(即首先检查用户是否在 HTTP 上,然后将他重定向到 HTTPS,然后初始化会话,然后将他重定向到 oauth 端点)——我个人推荐它。
一些 oauth 提供者在用户完成身份验证时为 url 获取参数以重定向用户。您可以使用它并将其会话 ID 作为参数发送。 - 我不建议这样做,因为那样您可能会将客户端的会话 ID 暴露给攻击者。
祝你好运!
【讨论】:
我在我的网站上使用 HTTP。我将用户重定向到 HTTPS 服务器。然后 HTTPS 服务器重定向到我的 HTTP 网站。我在我的 HTTP 站点中设置了 cookie。如果这是一个问题,我不会在每个请求中都有这个问题吗?我几乎在 %0.5 个请求中遇到了这个问题。 Cakephp 使用 cookie 来保持 http 和 https 之间的会话。 0.05% 是禁用 cookie 的浏览器和/或不支持跨 http 和 https 使用相同 cookie 的浏览器。 @trante,阅读我更新的答案。我认为它有你需要的信息。 我很确定即使是启用 cookie 的浏览器也有这个问题。我没有机会在我的服务器中使用 HTTPS 方案。我会更深入地了解该方案是否会导致问题。 如果他的 Web 服务器上只运行 HTTP,则传输到 OAuth 的返回 url 不能是 HTTPS。因此,尽管这是一个很好的建议,但我认为它不适用于这里,不是吗?【参考方案2】:我想 CBroe 在这里很赚钱。我之前也遇到过这种情况(不是专门针对 OAuth,而是针对设置会话 cookie 的其他重定向)。
更多信息在这里: Losing session variables after redirect
【讨论】:
我使用 CakePHP 的重定向功能将用户重定向到 API 服务器。它会自动运行 exit():github.com/cakephp/cakephp/blob/2.5/lib/Cake/Controller/… 我整理了一份要检查的清单...我不知道它是否与您的情况有关...***.com/questions/17242346/… @dayuloli 奇怪的是,这种情况很少发生。大多数登录以成功结束。 @trante 由于我在 CakePHP 和 AJAX 请求方面遇到了很大的问题,因为缺少“exit();”,所以你一定要试一试。【参考方案3】:如果会话 ID 未设置或者我们可以说与服务器不同,为什么不检查会话 ID 是否设置?另一种方法是,如果我们将会话变量设置在一个临时变量中,那么当它为空白时,它会附加到我们的会话变量中。
【讨论】:
当用户返回我的网站时,CakePHP 会重新生成会话 ID。在旧会话销毁的情况下,我不知道旧会话 ID 是什么。旧会话 ID 的 cookie 不存在。 即使我将会话 ID 设置为临时变量,当用户返回时,我的应用程序也不知道旧会话 ID,因为 cookie 不存在。临时变量在另一个用户不知道的会话中。【参考方案4】:在所有控制器的开头写下:
!session_id() ? session_start() : '';
我不知道为什么,但我自己也遇到过同样的问题。我发现在 CakePHP 中使用 OAuth 重定向时会话 ID 会以某种方式丢失。上面的行确保会话 id 始终存在。希望这会有所帮助。
【讨论】:
您显然从未使用过 CakePHP Sessions。你永远不会在任何地方的控制器中使用session_start()
。
@Muntasir CakePHP 有自己的会话处理程序,其工作方式与 PHP 内置会话略有不同。以上是关于OAuth 重定向后会话丢失的主要内容,如果未能解决你的问题,请参考以下文章