什么是Cookies?
Cookies是一些数据,存储于我们电脑上的文本文件中。由于cookie多用于在客户端和服务端交互通信,所以前后端语言都可存取cookie(例如前端JavaScript,后端PHP)。当web服务器向浏览器发送web页面时,在连接关闭后,服务端不会记录用户的信息。Cookies的作用就是用于解决“如何记录客户端的用户信息”
:
- 当用户访问web页面时,用户的名字可以记录在Cookies中。
- 在用户下一次访问该页面时,可以在Cookies中读取用户的访问记录。
一、Cookies存储方式
Cookies是以名/值对的形式存储。例如:
username=XiaoMing
当浏览器从服务器上请求web页面时,属于该页面的Cookies会被添加到请求中。服务端通过这种方式来获取用户的信息。
二、使用JavaScript来操作Cookies
JavaScript可以使用document.cookie属性来创建、读取、及删除cookies。
创建
- 创建Cookies.
document.cookie="username=XiaoMing";
- 我们同时可以为cookie设置一个过期时间(expires属性,为UTC或GMT格式)。默认情况下,cookie在浏览器关闭时删除:
document.cookie="username=XiaoMing;expires=Thu,18 Dec 2013 12:00:00 GMT"
- 还可以使用path参数告诉浏览器cookie存放的路径。默认情况下是当前的页面。
document.cookie="username=XiaoMing;expires=Thu,18 Dec 2013 12:00:00 GMT;path=/"
读取
- 我们可以用JavaScript来读取cookie。例如:
var cookieData=document.cookie;
- **注意:**document.cookie将以字符串的格式返回所有cookies。例如:
cookie1=value;cookie2=value;cookie3=value;
修改
- 在Javascript中,修改cookie类似于创建cookies。例如:
document.cookie="username=LiangJingRu;expires=Thu,18 Dec 2013 12:00:00 GMT;path=/"
这样旧的cookie将被覆盖。
删除
- 删除cookie非常简单,只需将过期时间设置为一个已过去的时间即可。
document.cookie="username=;expires=Thu,05 Jan 2015 00:00:00 GMT";
- 注意: 当想删除时不必指定cookie的值。username就没有指定值。
三、Cookie字符串
- document.cookie属性不是一个普通的文本字符串。即使我们在document.cookie中写入一个完整的cookie字符串,当我们重新读取该cookie信息时,cookie信息是以名/值对的形式展示的。如果您设置了新的cookie(新的cookie指的是,cookie中的名称是新的。),则旧的cookie不会被覆盖,新cookie将添加到document.cookie中,所有当重新读取document.cookie时,会显示:
cookie1=value;cookie2=value;cookie3=value;
- 如何在这么多cookies中,找到一个指定的cookie?我们可以用一个函数,在Cookie字符串中查找cookie值。
四、示例
- 在这个例子,我将创建cookie来存储访问web页面的访问者的用户名。
- 首先,访问者访问web页面,访问者被要求填写自己的名字,该名字将会存储在cookie中。
- 访问者下一次访问页面时,他将会看到一个欢迎的消息。
在这个示例中,需要创建三个JavaScript函数:
- 设置cookie值的函数
setCookie(cookieName,cookieValue,cookieExpires){
var date=new Date();
date.setTime(date.getTime()+(cookieExpires*24*60*60*1000));
var expires="expires="+date.toUTCString();//变量expires成为了UTC格式的时间字符串
document.cookie=cookieName+"="+cookieValue+";"+"expires="+cookieExpires;
}
上示函数的参数:cookieName是cookie的名称,cookieValue是cookie的值,cookieExpires是cookie的过期时间。
2. 获取cookie值的函数
getCookie(cookieName){
var name=cookieName+"=";
var array=document.cookie.split(';');//document.cookie返回的是带有以‘;’分隔的字符串,运用split()将其转换为数组
for(var i=0;i<array.length;i++){
var en=array[i].trim();//去除数组值中的前后空格,避免因空格导致找不到值
if(en.indexOf(name)==0){//index()是返回en变量中第一次出现name字符串的下标,因为cookie值是以名/值对返回,所以“名”是在变量en的0下标可以匹配。
return en.substring(name.length,en.length);//参数分别为子字符串开始的下标以及结束的下标;返回字符串对象中指定位置的子字符串。
}
}
return "";
}
如果找到,则返回cookieName对应的值;否则返回空
3. 检测cookie值的函数
checkCookie(){
var userName=this.getCookie("userName");
if(userName!=""){
alert("欢迎"+userName+"再次到来");
}else{
userName=prompt("请填写你的姓名:","");//prompt()方法用于显示可提示用户进行输入的对话框。返回用户输入的内容;第一个参数是在对话框显示的文本,第二个参数是默认的输入文本
if(userName!=""&&userName!=null){
this.setCookie("userName",userName,30);
}
}
}
如果设置了cookie,则会弹出一个问候消息;否则弹出一个弹窗,用于询问访问者姓名,并设置cookie和有效时间为30天。
4.在chorme的控制台查看cookie
五、Cookie注意事项
- cookie有大小限制,一般每个cookie不超过4kb,如果超过则cookie属性返回空。
- cookie存放在我们的电脑的文本中,容易被查看和修改,因此,不要存放重要的隐私消息。
- cookie的域概念(domain):因为浏览器需要有个安全的环境,所以不同的域是不能互相访问cookie的(除非设置什么来跨域访问)。
- cookie的路径:一个网页创建的cookie只能被与这个网页在同一目录或子目录下的网页访问,而不能被其它目录下的网页访问。
- 一个网站可以创建第一个cookie,都存在同一个文件中。
- cookie 无法跨域
六、详细讲解Cookie的域概念与路径概念
路径概念(routing):
- cookie一般在用户访问web页面被创建,但是该创建的cookie并不是只能在该页面才能被访问。默认情况下,只要与创建cookie的页面是同一个目录或者是该目录下的子目录页面都可以访问该cookie。
- 举个例子:在“http://www.abc.com/boke/”这个页面创建cookie,则在“/boke/”这个路径下的子目录,例:“http://www.abc.com/boke/efc.html”都可以访问上面的cookie。那么“http://www.abc.com”或者“http://www.abc.com/xxx/”都不可以访问上面的cookie。
- 那么怎样才能让上级目录和其它目录页面访问上面的cookie?只需将cookie的路径path设在(’/’)根目录即可。这样所有的页面都可以访问该cookie。
域概念(domain):
- 路径能解决同一个域下共享cookie,但同域之间要怎样实现cookie共享呢?
- 所谓的“同域”:例www.abc.com和xxx.abc.com公用一个有关联的域名“abc.com”,那么www.abc.com和xxx.abc,com要共享cookie,则需要用到cookie的domain属性,同时需将路径path设为根目录。
document.cookie="userName=XiaoMing;path=/;domain=abc.com";
七、cookie安全性
通常cookie是通过http连接传递数据,但http是无安全传输数据,容易被盗取cookie。要做到对数据加密,则要设置cookie的secure属性。如果cookie设置了secure,则前后端交互就会通过https或其它其他安全协议传输数据。
document.cookie="userName=XiaoMing;secure";
注意: 加入了secure,仅仅只是对传输过程的cookie加密。自己主机的cookie并不会被加密。
什么是Session
- session是另一种记录服务器和客户端会话记录的机制,是服务端有状态化。
- session是以cookie为基础来实现的,session存储在服务器端,sessionId作为session唯一标识符,sessionId会被存储到客户端的cookie中。
一、session的认证流程:
- 在用户第一次向服务器发起请求,服务器会根据用户提交的信息,创建对应的Session。
- 这个请求会返回此Session的唯一标识符SessionId给客户端。
- 客户端收到响应信息后,会将SessionId信息存入Cookie中,同时Cookie也记录着SessionId属于哪个域名。
- 此后,在Cookie有效的时间发起请求,请求会自动判断此域名是否存在Cookie信息中,如果存在,则自动将Cookie信息一并发送给服务端,因为SessionId存在Cookie中,所以服务端也就获得了SessionId,根据SessionId查找对应的Session信息,如果能找到对应Session信息,则可执行更深入的操作,否则说明该用户不存在或登录失效。
- 目前session大多数系统用来验证用户登录状态。
二、Cookie和Session的差异
- 存储容量:已知Cookie容量不超过4kb,但session的容量远大于cookie,但别忘了session存储在服务端,session容量过大,会影响服务器的性能。
- 有效时间:Cookie的有效时间可设置长点。
- 存取数据类型不同:Cookie只支持字符串类型,而Session可以为任意类型。
- 安全方面:由于Session存储于服务端,则Session更加安全。
什么是Token
一、Access Token(访问令牌)
- Token一般由uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)组成。
- 是访问API时需要的资源凭证。
- 支持在移动端设备使用。
- token认证是一种服务端无状态认证方式,服务端没有存放token数据。服务端在接收请求时,用算法解析token来认证,用解析token所花费的时间来代替了session所花费的存储空间,因为当session存储于数据库,每次认证都查询数据库匹配sessionId,造成数据库压力过大。
二、token的认证流程
- 用户在客户端使用用户名和密码请求登录。
- 服务端收到请求,验证用户名和密码。
- 验证成功后,服务端会签发一个 token 并把这个 token 返回给客户端。
- 客户端收到token,会把它存储在cookie或者localStorage里。
- 当客户端获得token之后,再向服务端请求数据时,都需要用刚返回的token作为资源凭证。每一次请求都需要把token放在Http的Header里。
- 服务端收到请求,然后去验证请求里携带着的token,如果验证成功,就向客户端返回请求的数据。
三、Refresh Token(刷新令牌)
- 这是另一种token。
- refresh token的作用仅仅用于刷新access token的token以生成新的access token。如果不是用refresh token去刷新token,则每次刷新都要用户输入用户名和密码,这给用户的体验非常不好。通过refresh token则无需用户做多余的操作。
- 通常Access token的有效期比较短,当Access token失效了,可以用refresh token去刷新Access token,只有当refresh token失效了,用户才需重新登陆账号。
- refresh token以及过期时间是存储在数据库中,只有申请新的Access token时才会去验证。
四、session和token的差异
- token安全性更高,每次请求都需要token。
- session使服务端和客户端通讯有状态化,而token是无状态化。
- 使用token,可以降低数据库压力。
什么是JWT(重点)
JWT是JSON Web Token的简称,是当前最流行的跨域认证解决方案。JWT的声明一般用在身份提供者和服务提供者间传递被认证的用户信息,以便从服务器获得数据资源。例如用在用户登录上。
一、JWT认证流程
- 用户从客户端发送用户名和密码,服务端认证后会返回给客户端一个JWT,客户端将token保存在cookie或者localStorage中。
- 当服务端接收到请求,服务端会检查请求的header中的Authorization中的JWT信息,如果认证成功,则可以继续访问资源。
- 因为JWT的使用不用到cookie,所以你可以使用任何域名来提供你的API服务,这就说明不用担心CORS(跨域资源共享问题)。
二、3种使用方式
- 当用户希望访问一个受保护的资源,需要在请求的header的Authorization字段中使用Bearer模式来添加JWT。即:Authorization:Bearer;
- 跨域的时候,可以把JWT放在Post请求的数据体里。
- 通过URL传输:http://www.abc.com/user?token=xxx