> php教程 > PHP开发 > 본문

PHP에서 SESSION이 만료되지 않도록 하는 방법 원리 및 솔루션 소개

高洛峰
풀어 주다: 2016-12-24 09:29:58
원래의
1252명이 탐색했습니다.

PHP에서 SESSION을 유지하는 방법과 이에 따른 몇 가지 생각. 최근 프로젝트에는 비교적 큰 형식이 포함되어 있어 많은 사용자가 이를 완료하는 데 많은 시간이 걸렸습니다. SESSION을 제출하자마자 발견했고 SESSION이 만료되어 시스템이 종료되었으므로 SESSION을 설정하고 온라인으로 유지하는 방법을 연구해야 했습니다.

세션이란 무엇인가요?
WIKI 설명에 따르면 SESSION은 두 통신 장치 사이에 존재하는 상호작용 정보로, 특정 시점에 형성되어 일정 기간이 지나면 만료됩니다. 일반적인 세션에는 TCP 세션, 웹 세션(HTTP 세션), 로그인 세션 등이 포함됩니다.

OSI 모델에서 세션 구현의 다양한 위치에 따라 SESSION은 주로 여러 유형으로 구분됩니다. 하나는 WEB SESSION(HTTP SESSION) 및 텔넷 원격 로그인 세션을 포함한 애플리케이션 계층 세션입니다. 구현에는 SIP(Session Initiation Protocol) 및 인터넷 전화 통화가 포함됩니다. TCP SESSION은 전송 계층에서 구현됩니다.

이 기사에서는 주로 WEB SESSION에 대해 설명합니다. 일반적으로 클라이언트 측 SESSION과 서버 측 SESSION이 Java Bean에서 제공하는 가장 일반적인 유형입니다.

SESSION은 어떤 일을 하나요?
컴퓨터 분야, 특히 네트워크에서는 SESSION이 특히 널리 사용됩니다. 대화(Dialogue), 대화 등으로도 불릴 수 있습니다. 일반적으로 두 통신 장치 간에 저장되는 상태를 의미하기도 합니다. 사용자 간 및 컴퓨터 간(로그인 SESSION).

Stateless 통신과 달리 SESSION은 일반적으로 통신 상태를 저장하는 데 사용됩니다. 따라서 두 통신 당사자 중 적어도 하나는 SESSION의 기록을 저장해야 둘 간의 통신이 이루어집니다.

SESSION(WEB SESSION)은 어떻게 구현되나요?
브라우저와 서버 간에 HTTP 통신이 수행될 때 일반적으로 상태를 식별하기 위해 HTTP 쿠키가 포함됩니다. 일반적으로 SESSION에는 사용자의 일부 확인 정보와 수준이 기록됩니다.

여러 프로그래밍 언어에서 가장 일반적으로 사용되는 HTTP 세션 토큰은 JSESSIONID(JSP), PHPSESSID(PHP), ASPSESSIONID(ASP)입니다. 이 식별자는 일반적으로 해시 함수에 의해 생성되며 이를 고유하게 나타낼 수 있습니다. 사용자 ID는 서버가 클라이언트와 통신할 때 GET 또는 POST 매개변수로 클라이언트에 저장됩니다.

SESSION을 구현하는 방법에는 일반적으로 서버측 SESSION과 클라이언트측 SESSION의 두 가지 방법이 있습니다. 두 가지 방법 모두 장점과 단점이 있습니다.

서버 측 SESSION은 구현하기 쉽고 상대적으로 효율적이지만 로드 밸런싱이나 고가용성 요구 사항의 경우 내부에 저장 장치가 없으면 처리하기가 더 어렵습니다. 시스템. 파일 시스템을 공유하거나 고객이 하나의 서버에만 로그인하도록 하여 로드 밸런싱을 달성할 수 있지만 이렇게 하면 효율성이 떨어집니다. 스토리지가 없는 장치의 경우 서버 측 SESSION 구현은 RAM을 사용하여 해결할 수도 있습니다(참조 6 참조). 이 방법은 클라이언트 연결이 제한된 시스템(예: 라우팅 또는 액세스 포인트 장치)에 효과적입니다.

클라이언트 측 SESSION을 사용하면 로드 밸런싱 알고리즘 방지 등 서버 측 SESSION의 일부 문제를 해결할 수 있지만 그 자체로 몇 가지 문제가 발생할 수도 있습니다. 클라이언트 SESSION은 쿠키와 암호화 기술을 사용하여 서로 다른 요청 사이의 상태를 저장합니다. 각 동적 페이지가 끝나면 현재 SESSION이 계산되어 클라이언트로 다시 전송됩니다. 요청이 성공할 때마다 서버가 사용자의 신원을 "기억"할 수 있도록 쿠키가 서버로 전송됩니다. 클라이언트 SESSION의 가장 중요한 문제는 보안입니다. 쿠키가 하이재킹되거나 변조되면 사용자 정보의 보안이 상실됩니다.

PHP에서 SESSION을 어떻게 설정하나요?
PHP 개발 환경을 설정한 후 phpinfo()를 통해 SESSION 관련 부분을 볼 수 있습니다.
PHP V5.2.9 버전의 SESSION 모듈에는 총 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라는 쿠키를 볼 것입니다.


SESSION의 만료는 가비지 수집 메커니즘(Garbage Collection)에 따라 다릅니다. SESSION이 생성되면 클라이언트 스크립트가 서버에 파일로 저장됩니다. SESSION의 변수를 사용하면 SESSION 파일의 액세스 시간이 업데이트됩니다. 각 방문은 클라이언트에 저장된 SESSIONID를 기반으로 서버에 저장된 고유한 SESSION을 요청합니다. 클라이언트의 쿠키가 만료되면 서버의 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>
로그인 후 복사


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


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

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

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

早期的Apache版本并没有采用COOKIE的方式来存储PHPSESSID,而是采用的URL-rewrite,也就是每个URL后面都会加上 PHPSESSID=来表明它属于那个激活的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中文网!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!