Token 详解,以及与Cookie和Session的区别

news/2024/5/18 15:27:39 标签: cookie, token, session

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

基于 Token 的身份验证
基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便
大概的流程是这样的:
客户端使用用户名跟密码请求登录
服务端收到请求,去验证用户名与密码
验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

APP登录的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码,如果成功,以某种方式比如随机生成32位的字符串作为token,存储到服务器中,并返回token到APP,以后APP请求时,凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,失败返回错误信息,让他重新登录。其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。

那么我的问题来了: 1.服务器上的token存储到数据库中,每次查询会不会很费时。如果不存储到数据库,应该存储到哪里呢。 2.客户端得到的token肯定要加密存储的,发送token的时候再解密。存储到数据库还是配置文件呢?

token是个易失数据,丢了无非让用户重新登录一下,新浪微博动不动就让我重新登录,反正这事儿我是无所谓啦。
所以如果你觉得普通的数据库表撑不住了,可以放到 MSSQL/MySQL 的内存表里(不过据说mysql的内存表性能提升有限),可以放到 Memcache里(讲真,这个是挺常见的策略),可以放到redis里(我做过这样的实现),甚至可以放到 OpenResty 的变量字典里(只要你有信心不爆内存)。

token是个凭条,不过它比门票温柔多了,门票丢了重新花钱买,token丢了重新操作下认证一个就可以了,因此token丢失的代价是可以忍受的——前提是你别丢太频繁,要是让用户隔三差五就认证一次那就损失用户体验了。

基于这个出发点,如果你认为用数据库来保持token查询时间太长,会成为你系统的瓶颈或者隐患,可以放在内存当中。
比如memcached、redis,KV方式很适合你对token查询的需求。
这个不会太占内存,比如你的token是32位字符串,要是你的用户量在百万级或者千万级,那才多少内存。
要是数据量真的大到单机内存扛不住,或者觉得一宕机全丢风险大,只要这个token生成是足够均匀的,高低位切一下分到不同机器上就行,内存绝对不会是问题。

客户端方面这个除非你有一个非常安全的办法,比如操作系统提供的隐私数据存储,那token肯定会存在泄露的问题。比如我拿到你的手机,把你的token拷出来,在过期之前就都可以以你的身份在别的地方登录。
解决这个问题的一个简单办法
1、在存储的时候把token进行对称加密存储,用时解开。
2、将请求URL、时间戳、token三者进行合并加盐签名,服务端校验有效性。
这两种办法的出发点都是:窃取你存储的数据较为容易,而反汇编你的程序hack你的加密解密和签名算法是比较难的。然而其实说难也不难,所以终究是防君子不防小人的做法。话说加密存储一个你要是被人扒开客户端看也不会被喷明文存储……
方法1它拿到存储的密文解不开、方法2它不知道你的签名算法和盐,两者可以结合食用。
但是如果token被人拷走,他自然也能植入到自己的手机里面,那到时候他的手机也可以以你的身份来用着,这你就瞎了。
于是可以提供一个让用户可以主动expire一个过去的token类似的机制,在被盗的时候能远程止损。

在网络层面上token明文传输的话会非常的危险,所以建议一定要使用HTTPS,并且把token放在post body里。

session
session的中文翻译是“会话”,当用户打开某个web应用时,便与web服务器产生一次session。服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。

cookie
cookie是保存在本地终端的数据。cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
cookie的组成有:名称(key)、值(value)、有效域(domain)、路径(域的路径,一般设置为全局:”\”)、失效时间、安全标志(指定后,cookie只有在使用SSL连接时才发送到服务器(https)

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

cookiesession的区别
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie

5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中

tokensession 的区别
session 和 oauth token并不矛盾,作为身份认证 token安全性比session好,因为每个请求都有签名还能防止监听以及重放攻击,而session就必须靠链路层来保障通讯安全了。如上所说,如果你需要实现有状态的会话,仍然可以增加session来在服务器端保存一些状态

token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件;cookie就是写在客户端的一个txt文件,里面包括你登录信息之类的,这样你下次在登录某个网站,就会自动调用cookie自动登录用户名;sessioncookie差不多,只是session是写在服务器端的文件,也需要在客户端写入cookie文件,但是文件里是你的浏览器编号.Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端。


http://www.niftyadmin.cn/n/1496153.html

相关文章

django如何防止csrf(跨站请求伪造)

什么是CSRF 什么是CSRF 下面这张图片说明了CSRF的攻击原理: Django如何防止CSRF(跨站请求伪造) Django中如何防范CSRF Django使用专门的中间件(CsrfMiddleware)来进行CSRF防护。具体的原理如下: 1.…

装饰器 生成器

Python生成器、迭代器、装饰器 Python生成器、迭代器、装饰器 1.生成器(Generator) 1.列表生成式实现 最简单的生成器&#xff1a; g (x*x for x in range(10)) for i in g:print i 实现 函数方法实现稍复杂的生成器&#xff1a; def fib(max):n,a,b0,1,1while n<ma…

Express路由参数

Express路由参数 在Express框架中传递和接受get请求参数还有另外一种方式&#xff0c;称为路由参数。这种方式可以让请求方式非常的美观。也可以让路由代码更加利于阅读。开发者可以一眼就看出来请求当前路由需要传递哪些参数。 app.get(/find/:id,(req,res) >{console.lo…

如何快速接手并熟悉新项目

论文档的重要性 新项目,基本是之前完全没参与过的,我多么希望有<<xx项目说明文档>>,<<xx项目部署文档>>,<<xx项目历史记录文档>>等等, 但是,耳边响起李宗盛的歌声 "想得却不可得,你奈人生何?" 既然前人不种树,后人不可乘凉,…

10种软件开发中 over-engineering 的错误套路

别把「不要过度使用 Generic」误解成「不用 Generic」。也别把「不要写一些不必要的 Wrapper」误解成「不写不论什么 Wrapper」。我仅仅是在讲 over-engineering 这个事。仅仅是在提倡不搞野路子编程。套路1&#xff1a;攻城狮自觉得比业务人员聪明 攻城狮认为自己最聪明&#…

ES6入门到进阶(一):let、解构赋值、字符串模板、函数

一、简介 ES6 -> ECMA 标准 ES6 -> 2015年6月 ES6.0 每年6月份&#xff0c;发布一个版本 ES6环境: webpack3.xTraceur 二、let、const 2.1 关于定义(声明)变量 var a12; 之前let let a12 相当于之前的 var const 常量&#xff0c; 定义好了不能改变2.2 作用域: 全局作用域…

(volatile int)(x)与*(volatile int *)(x)

在stackoverflow上看到这个问题 http://stackoverflow.com/questions/22758232/why-is-access-once-so-complex 原答主已经回答的很仔细了,不过还不够直观,这里做个试验 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 //加子函数防止变量优化没了 5 void pfun…

如何快速上手新项目

不知道你有没有经历过一个五年或者更长工作年限的开发人员半路加入团队的情况&#xff0c;可能第一两个星期他会问一些业务或者技术问题&#xff0c;不过一两个月他就可能在指导那些初级开发人员了。 什么原因呢&#xff1f;因为他已经从过往经验里面总结出来一些套路了。 那么…