ホームページ  >  記事  >  php教程  >  PHP で SESSION が期限切れにならないようにする方法の原理と解決策の紹介。

PHP で SESSION が期限切れにならないようにする方法の原理と解決策の紹介。

高洛峰
高洛峰オリジナル
2016-12-24 09:29:581280ブラウズ

PHP で SESSION を維持する方法と、それによって生じるいくつかの考え 最近のプロジェクトには、多くのユーザーがそれを完了するのに多大な労力を費やした後、かなりの時間がかかったことがわかりました。送信時に SESSION の有効期限が切れたため、SESSION を設定し、SESSION をオンラインに維持する方法を検討する必要がありました。

セッションとは何ですか?
WIKIの説明によると、SESSIONとは、2台の通信機器間に存在する対話型の情報で、ある時刻に確立され、一定期間後に消滅するそうです。一般的なセッションには、TCP セッション、WEB セッション (HTTP セッション)、ログイン セッションなどが含まれます。

OSI モデルにおけるセッション実装のさまざまな場所に応じて、セッションは主にいくつかのタイプに分けられます。1 つは、WEB セッション (HTTP セッション) と Telnet リモート ログイン セッションを含む、セッション層の実装です。トランスポート層で実装されるプロトコル (SIP) とインターネット電話通話は TCP SESSION です。

この記事では主に WEB SESSION について説明します。大きく分けて、クライアント側 SESSION とサーバー側 SESSION の 2 種類があり、後者は Java Beans によって提供される最も一般的なものです。

セッションって何をするの?
コンピュータ分野、特にネットワークにおいては、SESSION が特に広く使われており、ダイアログ (Dialogue)、セッションなどとも呼ばれます。一般に、2 つの通信デバイス間で保存される状態を指します。ユーザーとコンピュータの時刻 (ログインセッション)。

ステートレス通信とは異なり、SESSIONは通常、通信状態を保存するために使用されるため、通信を行う2者のうち少なくとも一方がSESSIONの履歴を保存する必要があります。

SESSION(WEB SESSION)はどのように実施されるのですか?
ブラウザとサーバー間で HTTP 通信が実行されると、通常、ステータスを識別するために HTTP Cookie が含まれ、通常、ユーザーのいくつかの検証情報とレベルが記録されます。

いくつかのプログラミング言語で最も一般的に使用される HTTP セッション トークンは、JSESSIONID (JSP)、PHPSESSID (PHP)、ASPSESSIONID (ASP) です。この識別子は通常、ハッシュ関数によって生成され、ユーザーの ID を一意に表すことができます。サーバー上でクライアントと通信する際、GET または POST パラメーターとしてクライアントに保存されます。

SESSION を実装するには通常、サーバー側 SESSION とクライアント側 SESSION の 2 つの方法があります。どちらの方法にも独自の長所と短所があります。

サーバー側の SESSION は実装が簡単で比較的効率的ですが、負荷分散や高可用性の要件が発生した場合の処理​​がより困難になります。また、内生システムにストレージ デバイスがない場合にも使用できません。負荷分散は、ファイル システムを共有するか、顧客に 1 つのサーバーのみに強制的にログインさせることによって実現できますが、これでは効率が低下します。ストレージのないデバイスの場合、サーバー側の SESSION 実装は RAM を使用して解決することもできます (参考資料 6 を参照)。この方法は、クライアント接続が制限されているシステム (ルーティングまたはアクセス ポイント デバイスなど) に効果的です。

クライアント側の SESSION を使用すると、負荷分散アルゴリズムの回避など、サーバー側の SESSION のいくつかの問題を解決できますが、それ自体がいくつかの問題を引き起こすこともあります。クライアント SESSION は、Cookie と暗号化テクノロジーを使用して、異なるリクエスト間の状態を保存します。各動的ページが終了すると、現在のセッションがカウントされ、クライアントに送り返されます。リクエストが成功するたびに、サーバーにユーザーの ID を「記憶」させるために Cookie がサーバーに送信されます。クライアント SESSION の最も重要な問題はセキュリティです。Cookie がハイジャックまたは改ざんされると、ユーザーの情報のセキュリティが失われます。

PHPでSESSIONを設定するには?
PHP 開発環境をセットアップした後、phpinfo() を通じて以下を含む SESSION 関連部分を表示できます。
SESSION モジュール、PHP V5.2.9 バージョンでは、合計 25 個の変数があります。その中で、日常の設定でよく使用されるものは次のとおりです:

session.cookie_lifetime 设置存储SESSIONID的cookie过期时间
session.name SESSION的COOKIE名称,默认为PHPSESSID
session.save_handler SESSION的存储方式,默认为FILE
session.save_path Fedora下面默认存储在/var/lib/php/session
session.gc_probability
session.gc_divisor
session.gc_maxlifetime 这三个选项用来处理GC机制发生的机率
session.cache_limiter (nocache,private,private_no_expire,public)
session.cache_expire 这两个选项是用来缓存SESSION的页面

まずは最初の質問について考えてみましょう。SESSION の有効期限が切れるまでにどれくらいの時間がかかり、どのように期限切れになるのですか? PHP プログラムで SESSION を使用する場合は、まず session_start() を参照する必要があります。この関数が実行されると、SESSION ファイルが SESSION の格納ディレクトリに生成されます (ファイル ハンドラーが使用されている場合)。同時に参照すると、サーバーはハッシュされた SESSION 名を保存する PHPSESSID という名前の Cookie を参照します。


SESSION の有効期限は、SESSION が作成された後、クライアント スクリプトが SESSION 内の変数にアクセスするたびに、サーバー上のファイルとして保存されます。 SESSION ファイルが更新されます。各訪問は、クライアントに保存されている SESSIONID に基づいて、サーバーに保存されている一意の SESSION を要求します。クライアントの Cookie の有効期限が切れると、サーバー上の SESSION ファイルはまだアクセスされていませんが、どの SESSION にアクセスするかを知ることはできません。有効期限が切れると、サーバー リソースが無駄に消費されます。

但是同时,如果我们希望用户的session马上过期的话,我们就可以通过设置cookie的办法来实现。SESSION的回收是在每次访问页面的时候进 行的,回收的机率由session.gc_probability,session_gc_divisor指定,默认士1/100。如果设置为1,则每次 超过了SESSION的生存周期去访问的话,SESSION一定会被回收。

两种需求:
1、保持SESSION不过期或延长SESSION过期时间;
2、使SESSION立即过期。

1、保持SESSION不过期和延长SESSION过期时间非常必要,特别是在内部应用系统中或者有很大的表单的时候。想想你的老板在填写一个表单,刚好 碰上午饭时间,留着这个表单等吃饭回来,填写完剩余的内容,提交后他看到什么,一般来说都是一个登录界面。想要提高用户体验,关键是要让老板的表单不出问 题,我们就必须延长SESSION的生存周期。

保持SESSION不过期和延长SESSION过期时间,可以通过设置session.gc_maxlifetime来实现,不过首先需要保证客户端的 cookie不会在gc执行回收之前失效。通过设置一个较长的gc_maxlifetime可以实现延长session的生存周期,可是对于不是所有请求 都会保持很久的应用来说,这么做对于服务器配置显然不是一个最佳的选择。
我们知道SESSION的回收机制是根据SESSION文件的最后访问时间来判断的,如果超过了maxlifetime,则根据回收机率进行回收。所以我们只需要定期的去访问一下SESSION就可以了,而这可以通过刷新页面来实现,根据这个思路,解决的方法就有了。

通过JS定期的去访问页面;
利用Iframe定期的刷新页面;

直接利用程序发送HTTP请求,这样就可以避免在页面中嵌入其他的元素;

下面是利用JS发送请求实现的保持SESSION不过期的实现方法,这样我们就只需要在需要SESSION保持长时间的页面(比如大表单页面)。

<script type=”text/javascript”>
 function keepMeAlive(imgName){
myImg = document.getElementById(imgName);
 if(myImg) myImg.src = myImg.src.replace(/\?.*$/, ‘?&#39; + Math.random());
}
window.setInterval(“keepMeAlive(‘phpImg&#39;);”, 4000);
 </script>

2b0523fb125092089a05bc06b76d15ca
其中URL后加入一个随机数是为了避免这个链接的请求被浏览器缓存。


2、使SESSION立即过期的方法就比较多了,我们可以session_destroy(),也可以用上面的思路,请求一个session_destroy的页面。

SESSION安全吗?
PHP的手册中明确写出:SESSION并不能保证储存在SESSION中的信息一定只能被他的创建者所看到。

如果想要安全的处理一些远程的操作,那么HTTPS是唯一的选择。最基本的,不要认为一个用户信息在SESSION中存在就认为这个用户一定就是他本人, 虽然SESSION中的信息会给你他已经经过了用户名和密码验证的假象。所以,如果需要做一些修改密码或者类似的事情的时候,让用户重新输入密码是一个比 较好的选择。

早期的Apache版本并没有采用COOKIE的方式来存储PHPSESSID,而是采用的URL-rewrite,也就是每个URL后面都会加上 PHPSESSID=6570879aef85ef8e10f1df5310b71b95来表明它属于那个激活的SESSION,新版的Apache已经将这个属性设置为默认关闭。

session.use_trans_id = 0;

所以从这个意义上来讲,延长SESSION的时间过长或者保持SESSION一直在线对于安全来说始终不是一件好事情。终极的解决办法就是用户提交跳转到 登录窗口,登录后又能够回到填写页面,并且所有的数据都还在。这个的实现方式现在用Ajax来解决应该没什么困难,每隔一定时间就把当前的用户数据 POST到一个存储位置,不管是XML或者JSON。


拾遗:
对于客户端不支持JavaScript的情况可以采用的方法:
1、写一个浮层,显示在最顶层,如果用户未禁用JS,则让浮层消失;
2、将所有的INPUT都设置为disable,然后再用JS设置为enabled;
以上这两种方式都是在JS被禁用的时候,所有功能都不能用,如何在JS被禁用的情况下使我们的应用仍然正常工作,这个貌似就比较困难。实现这个的所花的时间和所收到的效果大家要权衡一下。

更多PHP中怎样保持SESSION不过期 原理及方案介绍相关文章请关注PHP中文网!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。