且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

用户登录后,我需要在php会话中存储什么?

更新时间:2023-12-04 08:02:28

术语

  • 用户:访问者.
  • 客户端:安装在特定计算机上的特定网络功能软件.
  • Terminology

    • User: A visitor.
    • Client: A particular web-capable software installed on a particular machine.
    • 为了了解如何使会话安全,必须首先了解会话的工作方式.

      In order to understand how to make your session secure, you must first understand how sessions work.

      让我们看看这段代码:

session_start();

调用该命令后,PHP将查找名为PHPSESSID的cookie(默认情况下).如果找不到,它将创建一个:

As soon as you call that, PHP will look for a cookie called PHPSESSID (by default). If it is not found, it will create one:

PHPSESSID=h8p6eoh3djplmnum2f696e4vq3

如果找到,它将采用PHPSESSID的值,然后加载相应的会话.该值称为session_id.

If it is found, it takes the value of PHPSESSID and then loads the corresponding session. That value is called a session_id.

那是客户唯一会知道的事情.您添加到会话变量中的任何内容都将保留在服务器上,并且永远不会传输到客户端.如果更改$_SESSION的内容,则该变量不会更改.在您销毁它或超时之前,它始终保持不变.因此,尝试通过散列$_SESSION的内容或通过其他方式来混淆$_SESSION的内容是没有用的,因为客户端从不接收或发送该信息.

That is the only thing the client will know. Whatever you add into the session variable stays on the server, and is never transfered to the client. That variable doesn't change if you change the content of $_SESSION. It always stays the same until you destroy it or it times out. Therefore, it is useless to try to obfuscate the contents of $_SESSION by hashing it or by other means as the client never receives or sends that information.

然后,在新的会话中,您将设置变量:

Then, in the case of a new session, you will set the variables:

$_SESSION['user'] = 'someuser';

客户端将永远不会看到该信息.

The client will never see that information.

当恶意用户窃取另一用户的session_id时,可能会出现安全问题.如果没有任何检查,他将可以***地模拟该用户.我们需要找到一种唯一标识客户端(而非用户)的方法.

A security issue may arise when a malicious user steals the session_id of an other user. Without some kind of check, he will then be free to impersonate that user. We need to find a way to uniquely identify the client (not the user).

一种策略(最有效)涉及检查启动会话的客户端的IP是否与使用会话的人的IP相同.

One strategy (the most effective) involves checking if the IP of the client who started the session is the same as the IP of the person using the session.

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}

// The Check on subsequent load
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) {
    die('Session MAY have been hijacked');
}

该策略的问题在于,如果客户端使用负载平衡器,或者(在长时间会话中)用户具有动态IP,则会触发错误警报.

The problem with that strategy is that if a client uses a load-balancer, or (on long duration session) the user has a dynamic IP, it will trigger a false alert.

另一种策略涉及检查客户端的用户代理:

Another strategy involves checking the user-agent of the client:

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
}

// The Check on subsequent load
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) {
    die('Session MAY have been hijacked');
}

该策略的缺点是,如果客户端升级浏览器或安装插件(某些插件添加到用户代理),则用户代理字符串将更改,并会触发错误警报.

The downside of that strategy is that if the client upgrades it's browser or installs an addon (some adds to the user-agent), the user-agent string will change and it will trigger a false alert.

另一种策略是在每5个请求上轮换session_id.这样,session_id从理论上讲不会停留足够长的时间来被劫持.

Another strategy is to rotate the session_id on each 5 requests. That way, the session_id theoretically doesn't stay long enough to be hijacked.

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['count'] = 5;
}

// The Check on subsequent load
if(($_SESSION['count'] -= 1) == 0) {
    session_regenerate_id();
    $_SESSION['count'] = 5;
}

您可以根据需要组合所有这些策略,但同时也要兼顾其弊端.

You may combine each of these strategies as you wish, but you will also combine the downsides.

不幸的是,没有解决方案是万无一失的.如果您的session_id被盗用,那么您已经完成了很多工作.以上策略只是权宜之计.

Unfortunately, no solution is fool-proof. If your session_id is compromised, you are pretty much done for. The above strategies are just stop-gap measures.