HTTP 是一种没有状态的协议,也就是它并不知道是谁访问(或者说,没法区分,每次的访问和以前哪次的访问来自同一个客户端)。客户端用户名密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证
session(会话) 思想 1、当用户打开浏览器,首次访问某个网站(服务器),服务器会产生一个唯一的编号(sessionId),在响应时,把该编号发给客户端,客户端把该编号存储在cookie里。
2、当用户二次访问(如:点击超链)服务器,那么,请求时,会携带保存在cookie里的编号,服务器端拿到该编号后,会跟session中的编号进行对比,就能知道本次访问和哪次访问是同一个客户端。
业务场景: 1、客户端发送用户名和密码,请求登录
2、服务端收到请求,去库验证用户名与密码
3、验证成功后,服务端种一个cookie或发一个字符到客户端,同时服务器保留一份session
4、客户端收到 响应 以后可以把收到的字符存到cookie
5、客户端每次向服务端请求资源的cookie会自动携带
6、服务端收到请求,然后去验证cookie和session,如果验证成功,就向客户端返回请求的库数据
express-sessionSession存储位置: 服务器内存,磁盘,或者数据库里
Session存储内容: id,存储时间,用户名等
客户端携带 : cookie自动带
1、引入session模块: var session = require(‘express-session’);
2、创建session中间件:
app.use(session(options));
示例:
app.use(session({
secret: 'recommend 128 bytes random string',
cookie: { maxAge: 20 * 60 * 1000 },//session的过期时间(没有错,cookie和session息息相关,所以,是用cookie.maxAge来设置session的过期时间)
resave: true,
saveUninitialized: true
})
);
3、保存变量:
req.session.变量名= 值;
4、获取变量:
req.session.变量名
示例:session 登录和其它需要验证身份的模块(如:添加,删除)
token现在比较流行。
思想在服务端不需要存储用户的登录记录,全部发给客户端**由客户端自己存(**cookie,localStorage)
1、客户端使用用户名跟密码请求登录(前端)
2、服务端收到请求,去验证用户名与密码 (后端)
3、验证成功后,服务端会签发(产生)一个 Token(加了密的字符串),再把这个 Token 发送给客户端(后端)
4、客户端收到 Token 以后可以把它存储起来,比如放在 cookie 里或者 Local Storage 里(前端)
5、客户端每次向服务端请求资源的时候需要带着服务端签发的 Token(前端)
6、服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
示例:vue项目(webserver)和nodejs项目(apiserver)使用token。
实现jsonwebtoken的安装引入
let jwt = require('jsonwebtoken')
生成签名(token)
let token = jwt.sign(payload, secretOrPrivateKey, [options, callback])
校验token
jwt.verify(token, secretOrPublicKey, [options, callback])
token删除
由客户端,负责删除,服务器端没有任何保存,所以,只需要在客户端删除就行。
示例:token 登录,其它需要验证身份的模块(如:添加,删除)
session vs token| session | token | |
|---|---|---|
| 服务端保存用户信息 | √ | × |
| 避免CSRF攻击 | × | √ |
| 多服务器粘性问题 | 存在 | 不存在 |
多服务器粘性问题
当在应用中进行 session的读,写或者删除操作时,会有一个文件操作发生在操作系统的temp 文件夹下,至少在第一次时。假设有多台服务器并且 session 在第一台服务上创建。当你再次发送请求并且这个请求落在另一台服务器上,session 信息并不存在并且会获得一个“未认证”的响应。这时候,就需要把在第一台服务器上保存的session给其它服务器上也保存。然而,在基于 token 的认证中,这个问题很自然就被解决了。没有粘性 session 的问题,因为在每个发送到服务器的请求中这个请求的 token 都会被拦截
对于注销登录来说,token只需要在客户端删除就行。
如何保存信息给浏览器(cookie)1、前端保存:
cookie/localstorage
2、后端操作cookie:
服务器给浏览器种cookie: cookie-parser
cookie的创建(express会将其填入Response Header中的Set-cookie):
格式:
1、添加cookie
res.cookie(name, value [, options]); //参数: name: cookie名 value: 类型为String和Object。 Option: 类型为对象,可使用的属性如下: domain:cookie在什么域名下有效,类型为String,。默认为网站域名 expires: cookie过期时间,类型为Date。如果没有设置或者设置为0,那么该cookie只在这个session有效 maxAge: 实现expires的功能,设置cookie过期的时间,类型为String,指明从现在开始,多少毫秒以后,cookie到期。 path: cookie在什么路径下有效,默认为'/',类型为String secure:只能被HTTPS使用,类型Boolean,默认为false
2、删除cookie
res.clearcookie(name [, options]);
3、获取cookie
req.cookies.键名 //cookie是在客户端保存,每次请求时会携带,所以,用req对象获取cookie
示例:
设置键为name,值为:baobao,可访问的域名为:.example.com,可访问的路径:/admin',只可以用https访问
res.cookie('name', 'baobao', {
domain: '.example.com',
maxAge:10000*1000,
path: '/admin',
secure: true
});
cookie的value为对象
res.cookie('cart', { items: [1,2,3] });
服务器给浏览器种cookie的同时在服务器上生成session: cookie-session



