Maison > Article > développement back-end > PHP cookie和session机制
各位大神我对cookie和session机制一直都搞的不是特别清楚,有没有好的资料让我学习学习,感激不尽
各位大神我对cookie和session机制一直都搞的不是特别清楚,有没有好的资料让我学习学习,感激不尽
其实你带着问题去搜索引擎找, 会得出很多答案的.
cookie和session解决了什么问题? 怎么解决这个问题的? 其实搞清楚了这两个问题, 它的运行机制你自然就会明白.
cookie和session解决了什么问题?
弥补了http协议的天生缺陷, 无状态的(无法辩认上个请求和下个请求是否来自同一个用户).
怎么解决的?
在服务器端保存一个
key=>value
的值, 并把这个key
通过cookie进行传送. 每次客户端请求的时候, 把这个key
带到服务器端, 服务器就能区分请求是否来自同一用户.
上面只是简单地回答了cookie和session的机制. 具体的答案可以带着这两个问题去搜索.
在你了解他们的实现原理之前,先区分好2者的角色。
Cookie——存在于浏览器之中的一种缓存数据,可以被浏览器关闭(在设置里)。如果浏览器关闭了Cookie,Cookie将不可用。现在一般没人关Cookie了。
既然Cookie是来源于浏览器,实质上任何人都可以动你的Cookie。安全吗?当然不安全。那这个时候如何做到安全?请使用Session,而且没有例外。
Session——顾名思义“会话”,它存储在服务器上,这有别于Cookie是存储在用户的浏览器里。而它是基于Cookie的。如果Cookie无效,Session也会无法正常使用。因为Session会将自己的Session_id放在Cookie中。每次与网站服务器通信时,服务器端的程序语言都可以获取Cookie中的这个session_id,从而读取服务器上存储的session数据。
session_id是非常重要的东西。如果Cookie关闭后还希望Sesion有用怎么办?每一个请求都在header里带一个kv,里面提供了session_id。。。BLABLABLA。。。我认为你现在还不需要学习这个,这只是题外话。
COOKIE——数据存储在用户当前所使用的浏览器(换一个浏览器,之前的COOKIE又没有了噢),安全性弱
接下来,怎么用Cookie和Session?你可以学习下。
session可以基于cookie实现,也可以基于get参数实现,虽然不安全.
看看下面用MySQL内存表实现会话存储的例子就大概知道session和cookie的关系了.
<code>CREATE TABLE sessions ( user_id int(10) unsigned NOT NULL, session text NOT NULL, md5 char(32) NOT NULL, PRIMARY KEY (user_id) ) ENGINE=MEMORY DEFAULT CHARSET=utf8; 其中: user_id存储的是用户ID,作为主键. session存储的是用户的会话数组经过serialize或json_encode后的字符串. md5存储的是session字段的MD5值,用于实现Check And Set版本号乐观锁: --读取会话 SELECT session, md5 --写入会话时需要用到这里查出来的md5,就是下面的$last_md5 FROM sessions WHERE user_id = $user_id --写入会话 UPDATE sessions SET session = $str, md5 = md5($str) WHERE user_id = $user_id AND md5 = $last_md5 --检查MD5,确保session字段没有被修改过</code>
基于数据库实现一套自定义的cookie会话机制.
这个cookie既要做到认证用户,又要做到不能被伪造和破解.
<code>//保护用户密码的盐 $salt = sha1(uniqid($user_id.'_'.getmypid().'_'.mt_rand().'_', true)); //数据库保存的用户密码($pwd_user是用户输入的密码明文) //可以先在浏览器端使用CryptoJS.MD5()哈希密码后传给服务器处理, //保证服务器对用户密码明文的不知情,最好使用https加密传输避免被窃听和修改. //数据库保存的用户密码($pwd_user是用户输入的密码明文) $pwd_db = sha1($salt.sha1($pwd_user)); //password_hash返回值包含盐,这时不需要外部$salt参与. //password_verify可实现耗时恒定的字符串比较避免时序攻击. //$pwd_db = password_hash($pwd_user, PASSWORD_DEFAULT); //cookie里的盐 //其中$global_salt是配置里定义的全局盐,用来保护用户的盐,一旦修改,所有用户的cookie都将失效. $cookie_salt = sha1($global_salt.sha1($salt)); //最终生成的cookie内容 $cookie = base64_encode($user_id.'|'.$cookie_salt); //如果你需要高安全性,还可以使用AES(MCRYPT_RIJNDAEL_256)对整个cookie的内容做一次加密. //$cookie = mcrypt_aes($cookie, $key); //设置cookie,这里把过期时间设为604800秒(60*60*24*7,一周) setcookie('sessid', $cookie, time()+604800, '/', '', false, true); //解密cookie //$cookie = mdecrypt_aes($_COOKIE['sessid'], $key); //解码分割后拿到里面的$user_id和$cookie_salt //根据$user_id查询$salt拼出$cookie_salt,然后跟cookie里的$cookie_salt做对比,一致则通过cookie认证. $cookie = explode('|', base64_decode($_COOKIE['sessid'])); list($user_id, $cookie_salt) = $cookie;</code>