PHP网络技术(五)——cookie及记住用户名功能实现

PHP网络技术(五)——cookie及记住用户名功能实现

(原创内容,转载请注明来源,谢谢)

Cookie是存储在客户端(主要是浏览器)的信息,可以以此跟踪和识别用户。PHP无法直接操作Cookie,而是通过命令向浏览器发送命令,由浏览器对Cookie进行操作。

一、PHP设置cookie方式

1)setcookie(name,value,expire,path,domain,secure,httponly)

第一个参数是必填的,后面都是选填的。

name是cookie的名称,value不填则是空,value传输过程中会被使用urlencode进行转码。

expire是以秒计算的有效时间,如果有填的话则计时,浏览器关闭再打开还在;如果没填则计入内存,浏览器关闭再打开就没了。

path是有效路径,domain是作用域名(如果设置的不对会导致刷新或者重新打开浏览器时无法获取cookie),secure是加密传输(主要用于https)。

httponly如果是true则javascript无法操作此cookie,这有助于避免xss攻击。

2)setrawcookie

参数和setcookie都一样,区别在于value传输时不会被转码。

3)删除cookie方式

将cookie的expire设置成过去时间即可。

二、cookie存储机制

cookie通常用来存储相对不敏感的信息,例如记住用户名密码、登录控制等。由于cookie的存储是浏览器进行的操作,因此不同浏览器的存储机制也不相同。

1)存储位置

IE在每个域名下面保存一个文本文件,用于记录不同网站的cookie。Firefox将文件都存储在sqlite数据库中进行管理,但是为了安全,Firefox4以上的版本对文件进行了加密处理,只有特定的API才可以读取文件,其中存储了id、cookie名、值、对应的host、路径、失效时间、ishttponly等信息。

2)有效时间

如果设定cookie时,有设置expire,则关闭浏览器后再次打开浏览器,cookie还会存在。但是如果没有设定expire,则会被存入浏览器的内容,当浏览器关闭时cookie失效。另外,还有通过flash创建的cookie,称为flash shared object,其不受浏览器管理,即使浏览器清空数据仍会存在,只有格式化硬盘或者使用特定的软件才能删除。

3)数量限制

不同浏览器对每个域名下的cookie有所限制,IE8一个域名可以放50个cookie,firefox可以放150个。超过限制后,新的会把最旧的内容顶掉。

4)安全性

由于服务端和javascript都可以设置cookie,因此不够安全,可以通过ishttponly设置不允许javascript进行操作。但是即便如此,由于cookie可以用软件拼接进行发送,因此仍不安全,保密的信息不适合用cookie存储,如果要存储则必须进行加密。

5)占用资源

cookie使用可以带来好的用户体验,但是其占用带宽,由于客户端和服务端的通信都会带上cookie,因此,每次http请求会来回传送cookie共两次,占用上下行流量。因此不能滥用cookie,不要把cookie当作服务端的存储器进行使用。

三、跨域与P3P协议

cookie只能在一个应用中使用,即一个cookie只能有创建它的应用获得。但是如果一个项目有多个域名,需要实现跨域名获取cookie,则需要使用p3p协议。

1)P3P

P3P协议是为web用户提供对自己公开信息的更多控制,支持此协议的站点未浏览者声明他们的隐私策略。

P3P协议的使用,即要求共享某个cookie值的域名在cookie设置操作之前,加一个p3p的header头,且定义哪些域名可以访问该cookie,则被定义的域名可以直接获得此域名下的cookie。

2)实现方式

假设公司有两个域名,a.company.com和b.company.com,a域名需要共享某个cookie给b,方法如下。

a域名下的文件:

         header(‘P3P:CP=”CURa AMDa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOIDSP COR”’);
         setcookie(‘cookiename’,’value’,time()+3600, ‘/’, ‘.b.company.com’);

b域名下的文件:

         $_COOKIE[‘cookiename’];

3)注意事项

页面cookie必须设置expire,否则无法生效;利用iframe时,需要在获取的相应动态页头添加P3P的信息,否则IE会把iframe的cookie阻止。

如果仅有两个域名,此操作很方便,但是如果网站涉及很多的域名,则需要用完整的单点登录(SSO)方案,现有比较成熟的方案是CAS。

CAS有关的博客如下。

http://www.coin163.com/java/cas/cas.html

http://www.cnblogs.com/lr393993507/p/5231432.html

四、本地存储(localStorage)

设置cookie会占用较多带宽,且目前对每个域名下的cookie限制4kb。因此当有大量内容需要存储在本地时,需要使用本地存储技术,此技术使用javascript可以实现。

1)浏览器支持

用一段js代码可以判断浏览器是否支持本地存储:window.localStorage,如果是true则是支持,否则不支持。

2)增删改查

a.添加方式较为灵活,有三种方式:

window.localStorage.key1 = ‘val1’ 或localStorage[‘key1’] = ‘val1’ localStorage.setItem(‘key1’, ‘val1’),当设置同样的key时,后面的设置会覆盖前面的设置。

另外,当不知道键名时,可以使用window.localStorage.key(i)获取第i个键名,因此也可以相应的用键获取值,可以用for循环获取所有的键。

b. 获取方式同样灵活,也有三种对应的方式:

window.localStorage.key1 localStorage[‘key1’] ocalStorage.getItem(‘key1’)

c. 删除分为删除单个与全部删除:

删除单个采用localStorage.removeItem(‘key1’),全部删除采用clear()方法。

d. 事件监听

html5增加了对localStorage的事件监听,包括onstorage、storage等事件。

3)其他注意事项

任何格式的存储会被转换成字符串,因此如果需要存储数组等信息时,可以先用json将内容转换成特定格式的字符串,在取出时在转回去。

五、使用cookie实现记住用户名

1)功能

使用cookie实现记住用户名功能。

当每次重新刷新或加载页面,则去获取cookie,如果存在则赋值给输入框,如果不存在则将输入框制空。

设置保存用户名按钮,保存2小时。关闭浏览器再次打开仍然会存在。

设置取消保存,再次刷新则获取到空。

2)页面

a. 第一次打开

b. 输入用户名,点击记住用户名

c. 关闭浏览器,再次打开浏览器,发现用户名的cookie意见设置成功

d. 点击取消记住用户名

e. 刷新页面,发现用户名已经消失,关闭再次打开浏览器同样没有

3)实现源码

a. 引入jquery-1.12.3.min.js

b. index.php 样式页面以及js页面

<html>
         <head>
                   <title>记住用户名</title>
                   <scripttype="text/javascript"src="jquery-1.12.3.min.js"></script>             
         </head>
         <body>
 用户名:<inputid="username" />
                   <buttonid="btnSave">记住用户名</button>
                   <buttonid="btnCancel">取消记住用户名</button>
         </body>
</html>
<scripttype="text/javascript">
         $(function(){
                   //读取页面时获取cookie
                   $.post("user.php",{type:'init'},function(result){
                            $("#username").val(result);
                   });    
                   //保存用户名到cookie
         $("#btnSave").click(function(){
                            var username =$('#username').val();
                            $.post("user.php",{type:'set',username:username},function(result){
                                     alert('设置成功');
                                     location=location;
                            });                       
         });
                   //取消保存用户名到cookie,即直接设置失效
         $("#btnCancel").click(function(){
                            $.post("user.php",{type:'unset'},function(result){
                                     alert('取消成功');
                                     location=location;
                            });                       
         });   
         });   
</script>
c. user.phpcookie处理页面
<?php
//获取类型
$type =$_POST['type'];
if('init'== $type){
         //初始化页面,如果有内容则赋值,否则制空
         if(isset($_COOKIE['username'])){
                   echo $_COOKIE['username'];
         }else{
                   echo '';
         }
}elseif('set' == $type){
         //设置cookie
         $username = $_POST['username'];
         setcookie('username', $username,time()+36000, '/', '127.0.0.1', false, true);    
}else{
         //取消保存用户名到cookie,即直接设置失效
         setcookie('username', $username,time()-36000, '/', '127.0.0.1', false, true);     
}

4)注意事项

setcookie需要注意domain的设置,一开始domain我设置的不对,导致刷新页面一直没有反应。并且在设置过程用firefox查看本地cookie有设置。经过反复调试,发现domain设置的不对导致此结果。

——written by linhxx 2017.07.24

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-07-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏守望轩

Visual Studio 2008 每日提示(二十四)

#231、如何找到最后一次设置的环境保存的位置? 原文链接:Did you know… How to find what development settin...

3607
来自专栏性能与架构

Nginx 配置文件安全分析

简介 Gixy 是一个 Nginx 配置文件的分析工具,主要目标是防止由于不当的配置带来的安全问题 Gixy 是进行静态分析,只需要指定配置文件的路径,不需要启...

3129
来自专栏FreeBuf

路由器漏洞复现分析第二弹:CNVD-2018-01084

1月17日,CNVD公开了D-LinkDIR 615/645/815 service.cgi远程命令执行漏洞(CNVD-2018-01084),freebuf上...

2137
来自专栏cnblogs

Chrome调试技巧

1443
来自专栏前端萌媛的成长之路

NPM基本介绍(一)

1452
来自专栏Python攻城狮

文件的打开与关闭-IO1.文件的目的2.文件的打开与关闭 3.文件的读写 4.应用

就是把一些存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力

732
来自专栏IMWeb前端团队

跨平台web调试代理工具--whistle

whistle是基于Node实现的跨平台web调试代理工具,支持windows、mac、linux等所有安装了Node的操作系统,可以部署在本地机器、虚拟机或远...

2006
来自专栏钟绍威的专栏

scope='request'的bean预加载冲突

Error creating bean with name ‘authenticationSuccessServlet’: Scope ‘request’ is...

1756
来自专栏CodeSheep的技术分享

CentOS7上ElasticSearch安装填坑记

在 Linux 环境中,elasticsearch 不允许以 root 权限来运行!所以需要创建一个非root用户,以非root用户来起es

3949
来自专栏沈唁志

纯净得只剩下字的访问IP查询API

2302

扫码关注云+社区