资讯专栏INFORMATION COLUMN

大话javascript 7期:Cookie、Session和Token的那些事儿

tianren124 / 1999人阅读

摘要:服务器检查该,以此来辨认用户状态。如果为,表示删除该。防篡改签名服务器为每个项生成签名。服务端根据接收到的内容和签名,校验内容是否被篡改。算法得到的签名和请求中数据的签名不一致,则证明数据被篡改。

一、登录认证机制
随着互联网的不断发展,无论是网站还是app,一般都会要求用户注册/登录。主要的登录方式有账户密码登录、第三方登录(微信登录、QQ登录、微博登录等)

登录可分为三个阶段(登录验证、登录持续、退出登录);
登录验证指客户端提供账号/密码(或第三方平台(微信、qq)获取openid/unionid)向服务器提出登录请求,服务器应答请求判断能否登录并返回相应数据;
登录持续指客户端登录后, 服务器能够分辨出已登录的客户端,并为其持续提供登录权限的服务器。
退出登录指客户端退出登录状态。

二、保持登录持续状态的实现方式 为什么要保持登录状态的持续?

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

方案:客户端登录成功后, 服务器为其分配一个唯一的凭证, 客户端每次请求资源时都带上这个凭证;

实现方案

cookie 会话机制

session 会话机制

token 会话机制

三、Cookie、Session和Token Cookie(浏览器缓存) 1.什么是Cookie

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

cookie其实是补充http协议的无状态性的缺点,底层是通过服务器端在http响应消息中增加set-cookie字段来将cookie信息发送给浏览器端,因为它只能存4k,一般用来存浏览器的身份信息,浏览器在访问服务器的某些资源的时候,会在http请求头中将cookie数据传给服务器,这样服务器就知道是谁请求的了,但是如果用户清除了cookie,那就啥都没有了

2.Cookie的属性

1、Expires:该Cookie失效的时间,单位秒。

如果为正数,则该Cookie在maxAge秒之后失效(持久级别Cookie)。

如果为负数,该Cookie为临时Cookie,关闭浏览器即失效(会话级别Cookie),浏览器也不会以任何形式保存该Cookie。

如果为0,表示删除该Cookie。默认为–1;

2、Domain:
我们现在有二个域名。域名A:b.f.com,域名B:d.f.com;显然域名A和域名B都是f.com的子域名

如果我们在域名A中的Cookie的domain设置为.f.com,那么.f.com及其子域名都可以获取这个Cookie,即域名A和域名B都可以获取这个Cookie

如果域名A没有显式设置Cookie的domain方法,那么domain就为.b.f.com,不一样的是,这时,域名A的子域名将无法获取这个Cookie

HttpOnly: 这个属性是面试的时候常考的,如果这个属性设置为true,就不能通过js脚本来获取cookie的值,能有效的防止xss攻击

3.Cookie的操作

封装cookie的常用操作方法

设置cookie

读取cookie

删除cookie

var cookieUtil = {
    getItem: function (name) {
        var cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null;
        if (cookieStart > -1) {
            var cookieEnd = document.cookie.indexOf(";", cookieStart);
            if (cookieEnd == 1) {
                cookieEnd = document.cookie.length;
            }
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd))
        }
        return cookieValue;
    },
    setItem: function (name, value, expires, path, domain, secure) {
        var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
        if (expires) {
            cookieText += ";expires=" + expires.toGMTString();
        }
        if (path) {
            cookieText += ";path=" + path;
        }
        if (domain) {
            cookieText += ";domain=" + domain;
        }
        if (secure) {
            cookieText += ";secure";
        }
        document.cookie = cookieText;
    },
    unset: function (name, path, domain, secure) {
        this.setItem(name, "", new Date(0), path, domain, secure)
    }
}
CookieUtil.setItem("name", "tom"); // 设置cookie
console.log(CookieUtil.getItem("name"));//读取cookie
CookieUtil.unset("name")//删除cookie
4.Cookie防篡改机制
因为Cookie是存储在客户端,用户可以随意修改。所以,存在一定的安全隐患。
防篡改签名:服务器为每个Cookie项生成签名。如果用户篡改Cookie,则与签名无法对应上。以此,来判断数据是否被篡改。

原理如下:

服务端提供一个签名生成算法secret

根据方法生成签名secret(wall)=34Yult8i

将生成的签名放入对应的Cookie项username=wall|34Yult8i。其中,内容和签名用|隔开。

服务端根据接收到的内容和签名,校验内容是否被篡改。

举个栗子:
比如服务器接收到请求中的Cookie项username=pony|34Yult8i,然后使用签名生成算法secret(pony)=666。 算法得到的签名666和请求中数据的签名不一致,则证明数据被篡改。

Session(会话) 1.什么是session
session是一种服务器机制,是存储在服务器上的信息,主要配合cookie完成浏览器的身份认证和状态存储方式多种多样,可以是服务器的内存中,或者是mongo数据库,redis内存数据库中。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。

Session相对于cookie较安全点,当用户请求服务器的时候,服务器会把数据临时存下来,如果退出网站后,session会被销毁。

Session是基于cookie实现的,浏览器第一次访问服务器时,服务器创建一个Session,同时生成一个唯一的会话key,即sessionID。接着sessionIDsession分别作为keyvalue保存到缓存中,也可以保存到数据库中,然后服务器把sessionID通过set-cookie的方式写入浏览器,浏览器下次访问服务器时直接携带上cookie中的sessionID,服务器再根据sessionID找到对应的session进行匹配,来判断用户是否登录

2.session鉴权过程

【1】 客户端发起登录请求,服务器端创建session,并通过set-cookie将生成的sessionID写入的客户端的cookie中。
【2】 在发起其他需要权限的接口的时候,客户端的请求体的Header部分会携带sessionID发送给服务端。然后根据这个sessionId去找服务器端保存的该客户端的session,然后判断该请求是否合法。

3.cookie和session的区别

Token(身份令牌) 1.什么是token
token的意思是“令牌”,是用户身份的验证方式,最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。还可以把不变的参数也放进token,避免多次查库

浏览器第一次访问服务器,根据传过来的唯一标识userId,服务端会通过一些算法,如常用的HMAC-SHA256算法,然后加一个密钥,生成一个token,然后通过BASE64编码一下之后将这个token发送给客户端;客户端将token保存起来,下次请求时,带着token,服务器收到请求后,然后会用相同的算法和密钥去验证token,如果通过,执行业务操作,不通过,返回不通过信息;

2.token生成方式

浏览器第一次访问服务器时,服务器根据传过来的唯一标识userId,通过一些算法,加一个密钥,生成一个token,接着通过base64编码将token返回给客户端。客户端将token保存起来,下次请求时需要带着token,服务器收到请求后,用相同的算法和密钥去验证token

3.token和session的区别

token和session其实都是为了身份验证,session一般翻译为会话,而token更多的时候是翻译为令牌;
session服务器会保存一份,可能保存到缓存,文件,数据库;同样,session和token都是有过期时间一说,都需要去管理过期时间;
其实token与session的问题是一种时间与空间的博弈问题,session是空间换时间,而token是时间换空间。两者的选择要看具体情况而定。
虽然确实都是“客户端记录,每次访问携带”,但 token 很容易设计为自包含的,也就是说,后端不需要记录什么东西,每次一个无状态请求,每次解密验证,每次当场得出合法 /非法的结论。这一切判断依据,除了固化在 CS 两端的一些逻辑之外,整个信息是自包含的。这才是真正的无状态。
而 sessionid ,一般都是一段随机字符串,需要到后端去检索 id 的有效性。万一服务器重启导致内存里的 session 没了呢?万一 redis 服务器挂了呢?

sessionID是基于cookie实现的,而token不需要基于cookie。这就导致了sessionID只能用在浏览器上,对于原生的应用无法实现。原生的应用是不具备cookie的特性的。另外sessionID可以实现服务端注销会话,而token不能(当然你可以把用户登陆的token存入到redis中,但是不推荐token入库)

4.token的优点

Token作为用户认证的处理方式,有几个优点:

无状态,可扩展:不会在服务端存储用户的登录状态,可以很容易的实现服务器的增减

支持移动设备,对多类型客户端的支持良好

支持跨程序调用,各个接口之间的调用更方便

安全可靠

5.什么是JSON Web Token
JSON web Token,简称JWT,本质是一个token,是一种紧凑的URL安全方法,用于在网络通信的双方之间传递。一般放在HTTP的headers参数里面的authorization里面,值的前面加Bearer关键字和空格。除此之外,也可以在url和request body中传递。

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

如果你觉得这篇文章对你有所帮助,那就顺便点个赞吧,点点关注不迷路~

黑芝麻哇,白芝麻发,黑芝麻白芝麻哇发哈!

前端哇发哈

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/103598.html

相关文章

  • 登录那些事儿

    摘要:假如是在同一个域名下,例如与,因为允许设置到二级域名下,所以和是可以共享的,用户的信息可以通过可逆加密放在二级域名下的,并且设置,就可以一站登录,站站登录。 原文链接:BlueSun | 登录那些事儿 也不知道是什么原因,刚开始不久的职业生涯,在技术这条路走着走着,和「登录」总是有着一个不解之缘。还记得当初学习Web编程的时候么?不管是Java、.Net、PHP,继经典「Hello W...

    layman 评论0 收藏0
  • 大话javascript 5:跨域

    摘要:同源策略所谓同源是指协议,域名,端口均相同。同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。需注意的是由于同源策略的限制,所读取的为跨域请求接口所在域的,而非当前页。 一、什么是跨域 1.URL解析 URL (Uniform Resource Locator )统一资源定位符(URL)是用于完整地描述Internet上网页和其他资源的地址的...

    jzzlee 评论0 收藏0
  • 详解 CookieSessionToken

    摘要:由于是存在客户端上的,所以浏览器加入了一些限制确保不会被恶意使用,同时不会占据太多磁盘空间。签名是对前两部分的签名,防止数据被篡改。的作用最开始的初衷是为了实现授权和身份认证作用的,可以实现无状态,分布式的应用授权。 前言 无状态的HTTP协议 很久很久之前, Web基本都是文档的浏览而已。既然是浏览, 作为服务器, 不需要记录在某一段时间里都浏览了什么文档, 每次请求都是一个新的HT...

    Allen 评论0 收藏0
  • [聊一聊系列]聊一聊前端存储那些事儿

    摘要:如图图顾名思义,,是级别的存储。如笔者写的一篇浅析文章聊一聊百度移动端首页前端速度那些事儿读者们可以尝试使用。 欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码):https://segmentfault.com/blog/frontenddriver 在web开发越来越复杂的今天,前端拥有的能力也越来越多。其中最重要的一项莫过于web存储。...

    caige 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<