OAuth 重定向后会话丢失

2021-12-21 00:00:00 session cookies php cakephp session-cookies

我使用 CakePHP 2.4.我的网站上有一个 OAuth 登录.%99.5 的登录成功,但 %0.5 失败.我有这个错误几个月了.我尝试了很多东西来调试和记录,但仍然没有解决问题.虽然大部分请求都很好,但我需要解决一小部分.

I use CakePHP 2.4. I have an OAuth signin in my website. %99.5 of signins are successfull but %0.5 fails. I have this error for months. I tried many things to debug and log but still I didn't solve the problem. Although most of the requests are good I need to solve the small part.

场景是这样的:

  • 用户点击登录按钮
  • 我从服务器(例如雅虎、推特)获取请求令牌
  • 我将 oauth_token 保存在用户会话中
    例如会话 ID 是 aaa1234
  • CakePHP 创建 PHPSESSID cookie 并将会话 ID 保存在此 cookie 中.

  • User clicks Sign in button
  • I get request token from server (for example yahoo, twitter)
  • I save oauth_token in user's session
    for example session ID is aaa1234
  • CakePHP creates PHPSESSID cookie and save session id in this cookie.

我将用户重定向到 Twitter 服务器并且用户确认了我的申请

I redirect user to Twitter server and user confirms my application

对于场景 b:
用户现在似乎有了新的会话 ID.oauth_token 在新会话中找不到.但请注意,旧会话数据存在于 /tmp/sessions/ 文件夹中.

For the scenario b:
It seems like user has new session ID now. oauth_token can't be found in new session. But note that old session data exists in /tmp/sessions/ folder.

会话 aaa1234 的会话 ID cookie 不存在.但是我 2 天前设置的另一个跟踪 cookie 存在于 cookie 中.

Session ID cookie doesn't exists for session aaa1234. But another tracking cookie that I set 2 days ago exists in cookies.

我检查用户代理.
用户第一次来和用户从雅虎服务器回来时是一样的.

I check user agents.
It is same when user first comes and user comes back from Yahoo server.

此故障场景发生在 Chrome、Firefox、移动浏览器或其他浏览器中,因此我无法指责浏览器类型.
我应该检查什么来诊断?

This failure scenario happens in Chrome, Firefox, mobile browsers or other browsers, so I can't accuse browser type.
What should I check more to diagnose?

我的 CakePHP core.php 设置:

My CakePHP core.php settings:

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

Other settings are default as mentioned in file: https://github.com/cakephp/cakephp/blob/2.5/app/Config/core.php#L182

通过使用 这个答案,我检查了 cookie.20% 的错误用户禁用了 cookie.我询问了个人和用户确认的 cookie 选项.但似乎其他用户没有禁用 cookie.还有一些用户使用 Android WebViews 访问我的网站.在 WebView 客户端中,我确信我没有禁用 cookie.并且 99% 的 WebView 用户可以成功使用网站.

By using this answer I checked for cookies. 20% of the erroneous users disabled cookies. I asked personally and user confirmed cookie option. But it seems like other users didn't disabled cookies. Also some of users reach my website by using Android WebViews. In WebView clients I'm sure that I don't disable cookies. Also 99% of the WebView users can successfully use website.

推荐答案

由于方案之间的重定向,您的会话 ID 可能会丢失.如果您的用户在 HTTP 上收到会话 ID,然后在 HTTPS 上返回(或反之亦然),他的会话将丢失/替换为他以前的旧会话在那个计划上.

Your session id might be lost because of a redirect between schemes. In case your user received a session id on HTTP and then came back on HTTPS (or vice-versa) his session would be lost/replaced by an old session he had previously on that scheme.

这不是 100% 确定,但如果我是你,我会尝试看看(在过去的项目中也发生在我身上).

This is not 100% certain, but if I were you, I'd try to give it a look (it happened to me also in a past project).

编辑
说明:

客户端在 HTTP 上获得他们的会话,他们被重定向用于 oauth 目的,当他们回来时,他们通过 HTTPS 来.

The clients obtain their session on HTTP, they are redirected for oauth purposes, and when they come back, they come via HTTPS.

PHP 正常会话 ($_SESSION) 在 HTTP 和 HTTPS 之间移动时丢失.会话本身保留在服务器端,但是客户端丢失了 session_id,因此服务器无法识别他并且会话丢失了,所以我使用的是纯 PHP,100% 的客户端在途中丢失了会话背部.

PHP Normal sessions ($_SESSION) are lost when moving between HTTP and HTTPS. The session itself is kept on server side, but the client loses the session_id, thus the server doesn't recognize him and the session is lost, so I you were using pure PHP, 100% of your clients were to lose session on their way back.

CakePHP 通过保存会话 ID 的 cookie 来处理这个常见问题,然后当客户端返回时请求头中没有 session_id 时,由于 cookie,它的会话被恢复.0.05% 的失败客户是具有以下一项(或多项)情况的客户:

CakePHP handles this common problem via cookies that save the sesion id, and then when the client comes back without session_id on the request headers, its session is restored because of the cookie. The 0.05% of your clients that fails, are clients with one (or more) of the following:

  1. 禁用 Cookie(更常见)
  2. 在 HTTP/HTTPS 之间切换时不保留来自同一网站的 cookie 的浏览器(更为罕见)

可能的解决方案:

  1. 首先在 HTTPS 上初始化 cookie(即首先检查用户是否在 HTTP 上,然后将他重定向到 HTTPS,然后初始化会话,然后将他重定向到 oauth 端点) - 我个人推荐它.

  1. initialize the cookie on HTTPS to begin with (i.e first check if the user is on HTTP, then redirect him to HTTPS, then init the session, then redirect him to oauth endpoint) - I personally recommend it.

一些 oauth 提供者使用 url 参数在用户完成身份验证时重定向用户.您可以使用它并将其会话 ID 作为参数发送.- 我不建议这样做,因为那样你可能会将客户端的会话 ID 暴露给攻击者.

some oauth providers take parameters for the url to redirect the user when he finishes his authentication. You can use this and send its session id as a parameter. - I don't recommend this, because then you might expose your client's session id to attackers.

祝你好运!

相关文章