Cookie/Session机制详解

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份Session通过在服务器端记录信息确定用户身份

本章将系统地讲述Cookie与Session机制,并比较说明什么时候不能用Cookie,什么时候不能用Session。


1.1  Cookie机制

在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。

而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。

Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

1.1.1  什么是Cookie

Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。

由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。



查看某个网站颁发的Cookie很简单。在浏览器地址栏输入javascript:alert (document. cookie)就可以了(需要有网才能查看)。JavaScript脚本会弹出一个对话框显示本网站颁发的所有Cookie的内容,如图1.1所示。


图1.1  Baidu网站颁发的Cookie


图1.1中弹出的对话框中显示的为Baidu网站的Cookie。其中第一行BAIDUID记录的就是笔者的身份helloweenvsfei,只是Baidu使用特殊的方法将Cookie信息加密了。


注意:Cookie功能需要浏览器的支持。

如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。

不同的浏览器采用不同的方式保存Cookie。

IE浏览器会在“C:\Documents and Settings\你的用户名\Cookies”文件夹下以文本文件形式保存,一个文本文件保存一个Cookie。


1.1.2  cookie在php中使用

 2.新建cookie

setcookie(name,value,expire,path,domain,secure)
参数 描述
name 必需。规定 cookie 的名称。
value 必需。规定 cookie 的值。
expire 可选。规定 cookie 的有效期。
path 可选。规定 cookie 的服务器路径。
domain 可选。规定 cookie 的域名。
secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。

setcookie("name","aaaaaa",time()+3600,"/abc","baidu.com")

2.获取cookie

创建cookie后,就可以使用预定义变量$_COOKIE来获取cookie。不过,只能在其他页面获取cookie,因为在php中,被设置的cookie不会在本页面生效,除非该页面被刷新

实例:

?
1
2
3
4
<?php
  setcookie( "test" , "China" );
  echo "cookie is " . $_COOKIE [ "test" ];
  ?>

这里之所以要刷新页面,是因为cookie的值不会在调用setcookie()之后立即存储在 COOKIEhttpcookie _COOKIE中。

3.cookie的有效期

cookie有生命周期,也就是cookie存在的有效时间。可以设置第三个参数来设置有效时间。

实例(设置cookie有效时间的几种方式):

?
1
2
3
4
setcookie( "cookie_one" , "A" ,time()+60*60);    //cookie在一小时后失效
setcookie( "cookie_two" , "B" ,time()+60*60*24);  //cookie在一天后失效
setcookie( "cookie_three" , "C" , mktime (23,53,19,10,09,2020));  //cookie在2020年10月9日23时53分19秒失效
setcookie( "cookie_four" , "D" );   //关闭浏览器后cookie失效

4.cookie的有效路径

cookie中的路径用来控制设置的cookie在哪个路径下有效,默认为'/',在所有路径下都有效,也就是在整个服务器域名下都有效,当设定了其他路径之后,则只在设定的路径以及子路径下有效,例如:

?
1
setcookie( 'test' , time(), 0, '/path' );

上面的设置会使test在/path以及子路径/path/abc下都有效,但是在根目录下就读取不到test的cookie值。

一般情况下,大多是使用所有路径的,只有在极少数有特殊需求的时候,会设置路径,这种情况下只在指定的路径中才会传递cookie值,可以节省数据的传输,增强安全性以及提高性能。

5.删除cookie

删除cookie比较简单,也是通过setcookie()来实现的(不要使用unset()!!!)下面的代码就是个简单例子:

?
1
setcookie( "test" , "" );

通过将第二个参数设为空来达到删除cookie的目的。如果设置cookie时,为cookie提供了特定的值,那么在删除cookie时,仍然需要提供这些参数,以便PHP可以正确地删除cookie。

在发送 cookie 时,cookie 的值会自动进行 URL 编码。接收时会进行 URL 解码。如果你不需要这样,可以使用setrawcookie() 代替



1.1.3  Cookie的不可跨域名性

很多网站都会使用Cookie。例如,Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?或者Google能不能修改Baidu颁发的Cookie呢?

答案是否定的。Cookie具有不可跨域名性根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。

需要注意的是,虽然网站images.google.com与网站www.google.com同属于Google,但是域名不一样,二者同样不能互相操作彼此的Cookie。


注意:用户登录网站www.google.com之后会发现访问images.google.com时登录信息仍然有效,而普通的Cookie是做不到的。这是因为Google做了特殊处理。本章后面也会对Cookie做类似的处理。


1.1.4  Unicode编码:保存中文

中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。


提示:Cookie中保存中文只能编码。一般使用UTF-8编码即可。不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。


1.1.5  BASE64编码:保存二进制图片

Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。例如在Cookie中使用数字证书,提供安全度。使用二进制数据时也需要进行编码。

%注意:本程序仅用于展示Cookie中可以存储二进制内容,并不实用。由于浏览器每次请求服务器都会携带Cookie,因此Cookie内容不宜过多,否则影响速度。Cookie的内容应该少而精。


1.1.6  Cookie的修改、删除

Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。

如果要删除某个Cookie,只需要新建一个同名的Cookie,并将expire设置为目前之前的时间(time()-100),或新建一个同名cookie值设为空,并覆盖原来的Cookie。


注意:修改、删除Cookie时,新建的Cookie除value、expire之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。


1.1.9  Cookie的域名

Cookie是不可跨域名的。域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。隐私安全机制能够禁止网站非法获取其他网站的Cookie。

正常情况下,同一个一级域名下的两个二级域名如www.helloweenvsfei.com和images.helloweenvsfei.com也不能交互使用Cookie,因为二者的域名并不严格相同。如果想所有helloweenvsfei.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数,例如:


注意:name相同但domain不同的两个Cookie是两个不同的Cookie。如果想要两个域名完全不同的网站共有Cookie,可以生成两个Cookie,domain属性分别为两个域名,输出到客户端。


1.1.10  Cookie的安全属性

HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:


提示:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。


1.1.12  JavaScript操作Cookie

Cookie是保存在浏览器端的,因此浏览器具有操作Cookie的先决条件。浏览器可以使用脚本程序如JavaScript或者VBScript等操作Cookie。这里以JavaScript为例介绍常用的Cookie操作。例如下面的代码会输出本页面所有的Cookie。

<script>document.write(document.cookie);</script>

由于JavaScript能够任意地读写Cookie,有些好事者便想使用JavaScript程序去窥探用户在其他网站的Cookie。不过这是徒劳的,W3C组织早就意识到JavaScript对Cookie的读写所带来的安全隐患并加以防备了,W3C标准的浏览器会阻止JavaScript读写任何不属于自己网站的Cookie。换句话说,A网站的JavaScript程序读写B网站的Cookie不会有任何结果。



1.2  Session机制

除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力

1.2.1  什么是Session

Session 的工作机制是:为每个访问者创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,亦或通过 URL 进行传导。

当客户端禁用COOKIEsession_id将无法传递,此时SESSION失效。不过php5linux/unix平台可以自动检查cookie状态,如果客户端设置了禁用,则系统自动把session_id附加到url上传递。windows主机则无此功能。     

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。


Session也是一种key-value的属性对。


提示Session的使用比Cookie方便,但是过多的Session存储在服务器内存中,会对服务器造成压力。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。 


1.2.3  Session的生命周期


Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。


1.2.4  Session的有效期

由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。

Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(longinterval)修改。

Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()方法可以使Session失效。


1.2.5  Session的常用方法

Session中包括各种方法,使用起来要比Cookie方便得多。Session的常用方法如表1.2所示。


 Session_start() 
:开始一个会话或者返回已经存在的会话。
   说明:这个函数没有参数,且返回值均为true。如果你使用基于cookiesession(cookie-based sessions),那么在使用Session_start()之前浏览器不能有任何输出

注册SESSION变量:
PHP5
使用$_SESSION[‘xxx’]=xxx注册SESSION全局变量。和GETPOSTCOOKIE的使用方法相似。

● session_id()
    session_id() 
用于设定或取得当前session_idphp5中既可以使用session_id(),也可以通过附加在url上的SID取得当前会话的session_idsession_name
    
如果session_id()有具体指定值的话,将取代当前的session_id值。使用该函数必须在启动会话:session_start()前进行调用;

● 检查session是否存在?
    在以往的php版本中通常使用session_is_register()检查session是否存在,如果您使用$_SESSION[‘XXX’]=XXX来注册会话变量,则session_is_register()函数不再起作用。你可以使用
isset($_SESSION[‘xxx’])来替代。
● 更改session_id  
    session_regenerate_id()
 更改成功则返回true,失败则返回false
使用该函数可以为当前session更改session_id但不改变当前session的其他信息。例如:
<?php
session_start();
$old_sessionid = session_id();
session_regenerate_id();
$new_sessionid = session_id();
echo "原始 SessionID: $old_sessionid<br />";
echo "新的 SessionID: $new_sessionid<br />";
echo"<pre>";
print_r($_SESSION);
echo"</pre>";
?>
● session_name() 返回当前sessionname或改变当前sessionname。如果要改变当前sessionname,必须在session_start() 之前调用该函数。注意:session_name不能只由数字组成,它至少包含一个字母。否则会在每时每刻都生成一个新的session id.
session改名示例:
<?php
$previous_name = session_name("WebsiteID");
echo "新的session名为: $previous_name<br />";
?>

● 如何删除session
1unset ($_SESSION['xxx'])删除单个sessionunset($_SESSION['xxx']) 用来unregister一个已注册的session变量。其作用和session_unregister()相同。 session_unregister()PHP5中不再使用,可将之打入冷宫。
unset($_SESSION)  
此函数千万不可使用,它会将全局变量$_SESSION销毁,而且还没有可行的办法将其恢复。用户也不再可以注册$_SESSION变量。
2$_SESSION=array()删除多个session
3
session_destroy()结束当前的会话,并清空会话中的所有资源。。该函数不会unset(释放)和当前session相关的全局变量(globalvariables),也不会删除客户端的session cookie.PHP默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数。
    返回值:布尔值。
    功能说明:这个函数结束当前的session,此函数没有参数,且返回值均为true

   session_unset() 如果使用了$_SESSION,则该函数不再起作用。由于PHP5必定要使用$_SESSION,所以此函数可以打入冷宫了。

下面是PHP官方关于删除session的案例:
<?php
// 初始化session.
session_start();
/*** 删除所有的session变量..也可用unset($_SESSION[xxx])逐个删除。****/
$_SESSION = array();
/***删除sessin id.由于session默认是基于cookie的,所以使用setcookie删除包含session idcookie.***/
if (isset($_COOKIE[session_name()])) {
   setcookie(session_name(), '', time()-42000, '/');   注:最后必须到‘/’
}
// 最后彻底销毁session.
session_destroy();
?>

由此我们可以得出删除Session的步骤:
session_start()
$_SESSION=array()/unset($_SESSION['xxx'])
session_destroy()



1.2.6  Session对浏览器的要求

虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。

该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。

因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。


注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择“在新窗口中打开”时,子窗口便可以访问父窗口的Session。

如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。


● SESSION安全:
    会话模块不能保证存放在会话中的信息只能被创建该会话的用户看到。根据其存放的数据,还需要采取更多措施来主动保护会话的完整性。 
    评估会话中携带的数据并实施附加保护措施通常要付出代价,降低用户的方便程度。例如,如果要保护用户免于受简单的社交策略侵害(注:指在 URL 中显示的会话 ID 会被别人在电脑屏幕上看到,或被别的网站通过 HTTP Referer 得到等),则应该启用session.use_only_cookies。此情形下,客户端必须无条件启用 cookie,否则会话就不工作 
    有几种途径会将现有的会话 ID 泄露给第三方。泄露出的会话 ID 使第三方能够访问所有与指定 ID 相关联的资源。第一,URL 携带会话 ID。如果连接到外部站点,包含有会话 ID  URL 可能会被存在外部站点的 Referer 日志中。第二,较主动的攻击者可能会侦听网段的数据包。如果未加密,会话 ID 会以明文方式在网络中流过。对此的解决方式是在服务器上实施 SSL 并强制用户使用。 
    默认情况下,所有与特定会话相关的数据都被存储在由 INI 选项 session.save_path 指定的目录下的一个文件中。对每个会话会建立一个文件(不论是否有数据与该会话相关)。这是由于每打开一个会话即建立一个文件,不论是否有数据写入到该文件中。注意由于和文件系统协同工作的限制,此行为有个副作用,有可能造成用户定制的会话处理器(例如用数据库)丢失了未存储数据的会话。
        上面介绍函数下文将会用到,但还有一些有关session的函数也介绍一下:
 session_encode
    函数功能:sesssion信息编码
    函数原型:string session_encode(void);
    返回值:字符串
    功能说明:返回的字符串中包含全局变量中各变量的名称与值,形式如:a|s:12:"it is a test/";c|s:4:"lala"; a是变量名 s:12代表变量a的值"it is a test的长度是12 变量间用分号”;”分隔。
 session_decode
    函数功能:sesssion信息解码
    函数原型:boolean session_decode (string data)
    返回值:布尔值
    功能说明:这个函数可将session信息解码,成功则返回逻辑值true
Php5 不再使用session_id,而是把它变成一个常量SID,并保存在cookie中。如果客户端禁用了cookiephp会自动通过url自动传动传递SID,其条件是设置php.ini中的session.use_trans_sid = 1。此时即使客户端即使禁用了cookie也没关系了。
    strip_tags() 来输出 SID 以避免 XSS 相关的攻击。

Session跨页传递问题:
session跨页传递需要考虑三种情况:
①客户端禁用了cookie
②浏览器出现问题,暂时无法存取cookie
php.ini中的session.use_trans_sid = 0或者编译时没有打开--enable-trans-sid选项
为什么会这样呢?下面解释一下原因:
Session文件分为两部分:session变量保存在服务器端(默认以文件方式存储session);而session id则以cookie形式保存在客户端(注意:session默认是基于cookie)
    当用户的浏览器向服务器提出请求时,同时发送包含session idcookie(默认情况下)。服务器根据客户端提供的session id来得到用户的文件,即保存在服务器端的session变量值。事实上,session id可以使用客户端的Cookie或者Http1.1协议的Query_String(就是访问的URL“?”后面的部分)来传送给服务器,然后服务器读取Session的目录……。也就是说,session id是取得存储在服务上的session变量的身份证。当代码session_start();运行的时候,就在服务器上产生了一个session文件,随之也产生了与之唯一对应的一个session id,定义session变量以一定形式存储在刚才产生的session文件中。通过session id,可以取出定义的变量。跨页后,为了使用session,你必须又执行session_start();将又会产生一个session文件,与之对应产生相应的session id(:又会产生是有条件的,如果用户没有禁止Cookie的话,session id是可以隐藏的传过去的,也就是说不会产生新的session id,但如果禁止了Cookie的话,就需要手动传递session id来解决此问题了,见例2)),用这个session id是取不出前面提到的第一个session文件中的变量的,因为这个session id不是打开它的钥匙。如果在session_start();之前加代码session_id($session id);将不产生新的session文件,直接读取与这个id对应的session文件。
    PHP中的session在默认情况下是使用客户端的Cookie来保存session id,所以当客户端的cookie出现问题的时候就会影响session了。必须注意的是:session不一定必须依赖cookie,这也是 session相比cookie的高明之处。当客户端的Cookie被禁用或出现问题时,PHP会自动把session id附着在URL,这样再通过session id就能跨页使用session变量了。但这种附着也是有一定条件的,其一:“php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项;其二:运行PHP的服务器必须是unix/linux系统,windows不具备此项功能
     明白了以上的道理,我们就可以得出解决session跨页传递问题的三条途径:
1、设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项,让PHP自动跨页传递session id
2、手动通过URL传值、隐藏表单传递session id
3、用文件、数据库等形式保存session_id,在跨页过程中手动调用。
下面举例说明:
第一种情况:
page1.php
<?php
session_start();
$_SESSION['var1']="中华人民共和国";
$url="<a href="."/"s2.php/">下一页</a>";
echo $url;
?>
page2.php
<?php
session_start();
echo "传递的session变量var1的值为:".$_SESSION['var1'];
?>
运行以上代码,在客户端cookie正常的情况下,应该可以在得到结果中华人民共和国
现在你手动关闭客户端的cookie,再运行,可能得不到结果了吧。如果得不到结果,再设置php.ini中的session.use_trans_sid = 1或者编译时打开打开了--enable-trans-sid选项,又得到结果中华人民共和国

第二种途径:
s1.php
<?php
session_start();
$_SESSION['var1']="中华人民共和国";
$sn = session_id();
$url="<a href="."/"s2.php?s=".$sn."/">下一页</a>";    //PHP5定义了一个常量SID来表示session_id()$url还可以写成$url='<a href="page2.php?' . SID . '">下一页</a>';
echo $url;
?>
s2.php
<?php
session_id($_GET['s']);
session_start();
echo "传递的session变量var1的值为:".$_SESSION['var1'];
?>
第三种途径:
login.html
<!DOCTYPE html="">HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=??????">
</head>
<body>
请登录:
<form method="post" action="mylogin1.php">
用户名:<input type="text" ><br>
口 令:<input type="password" ><br>
<input type="submit" value="登录">
</form>
</body>
</html>
mylogin1.php
<?php
$name=$_POST['name'];
$pass=$_POST['pass'];
if(!$name || !$pass) {
    echo "用户名或密码为空,请<a href=/"login.html/">重新登录</a>";
    die();
}
if (!($name=="laogong" && $pass=="123")) {
    echo "用户名或密码不正确,请<a href=/"login.html/">重新登录</a>";
    die();
}
//注册用户
ob_start();
session_start();
$_SESSION['user']= $name;
$psid=session_id();
$fp=fopen("e://tmp//phpsid.txt","w+");
fwrite($fp,$psid);
fclose($fp);
//身份验证成功,进行相关操作
echo "已登录<br>";
echo "<a href=/"mylogin2.php/">下一页</a>";
?>
mylogin2.php
<?php
$fp=fopen("e://tmp//phpsid.txt","r");
$sid=fread($fp,1024);
fclose($fp);
session_id($sid);
session_start();
if(isset($_SESSION['user']) && $_SESSION['user']="laogong" ) {
     echo "已登录!";
}
else {
    //成功登录进行相关操作
    echo "未登录,无权访问";
    echo "<a href=/"login.html/">登录</a>后浏览";
    die();
}
?>

总结一下,上面的方法有一个共同点,就是在前一页取得session id,然后想办法传递到下一页,在下一页的session_start();代码之前加代码session_id(传过来的session id); 



注1:

我们都知道当在session 会话有基于cookie和基于url两种传递SESSIONID的方法。为了实现客户端禁止cookie发送的情况也不影响客户登陆网站,可以设置 php.ini中 session.use_trans_sid=1 ,表示当客户端浏览器禁止cookie的时候,页面上的链接会基于url传递SESSIONID。但是很多人仅仅设置了这一个选项并没有达到效果,本人也 遇到此问题,后来一番研究发现

php.ini 文件中还有两个选项

?
1
2
session.use_cookies=1
session.use_only_cookies=1

仔细琢磨上面的英文就会发现其意义

session.use_cookies表示是否开始基于cookies的session会话
session.use_only_cookies 表示是否只开启基于cookies的session的会话方式

所以如果想要在浏览器开启cookie的时候用基于cookie的方式,在未开启cookie的时候使用url的方式就进行如下设置(最常用的方式,推荐)

在php.ini文件中:

?
1
2
3
session.use_trans_sid=1
session.use_only_cookies=0
session.use_cookies=1

或者 在php程序中

?
1
2
3
ini_set ( "session.use_trans_sid" ,"1″);
ini_set ( "session.use_only_cookies" ,0);
ini_set ( "session.use_cookies" ,1);

如果不管浏览器是否开启cookie,都使用url的方式就进行如下设置(这个例子主要想说明一下设置session.use_only_cookies 和 session.use_cookies的区别)

在php.ini文件中

?
1
2
3
session.use_trans_sid=1
session.use_only_cookies=0
session.use_cookies=0

或者 在php程序中

?
1
2
3
ini_set ( "session.use_trans_sid" ,"1″);
ini_set ( "session.use_only_cookies" ,0);
ini_set ( "session.use_cookies" ,0);

动手自己试一试 你就会明白session.use_only_cookies 和 session.use_cookies的区别。



注2:

在js中可以通过doucument.cookie 来获得cookie数据,但中文会出现乱码,

解决思路:

1:写入Cookie时,先将其用Url编码,然后再写入

2:当我们读取时再Url解码即可

 

php两个函数 

urlencode()  

urldecode()

 

js两个函数 

decodeURI()  

encodeURI()  

5.5以前的版本是 escape   unescape



参考文档

http://blog.csdn.net/masterft/article/details/1640122

http://blog.csdn.net/drylandfish/article/details/244085

http://blog.csdn.net/fangaoxin/article/details/6952954/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值