理解Web中的Session
- 格式:pdf
- 大小:132.75 KB
- 文档页数:2
理解Web中的Session
===================================
Session ⼯作原理是什么?
===================================
因为 http 协议是⽆状态的, 对于服务器端来讲, 如何为不同的访问⽤户提供不⼀样的体验呢? ⽐如邮箱系统, 只有登录⽤户才能收发邮件.
这就需要服务器能识别每⼀个客户端访问, 知道哪些访问是来⾃⼀个同⼀个客户端, 显然这个事情光靠服务器端是做不到的, 需要浏览器配合
才⾏, 浏览器端 cookie 概念就这么产⽣了. Session ⼯作原理:
(1) 当⼀个 Session 第⼀次被启动时, 服务器端先产⽣⼀个唯⼀的 session id, 并为该 session id 分配⼀个内存区, ⽤来保存该 session 相关的
信息. 然后将该 id 存储到浏览器的 cookie 中, cookie name 为 JSESSIONID. (2) 浏览器每次访问, 都会带上本域下所有的 cookie, 包括这个 JSESSIONID cookie(应该是放到 Http Header 上的), 服务器端通过对⽐
JSESSIONID 和服务器内存中的 session id, 就能识别哪些访问是来⾃同⼀个客户端.
(3) 服务器端在每次访问中, 都可以在 JSESSIONID 对应的 session 内存区中记录⼀些信息, ⽐如最后⼀次的访问时间, ⽐如访问 IP 值, 以满
⾜业务需求.
===================================
Session 的⽤途有哪些?
===================================
1. 核⼼功能: 是识别每⼀个访问.
2. 基本功能: 做登录验证, 然后就能得到登录 id, 进⽽能完成权限验证.
核⼼功能和基本功能都由 Spring Web 框架提供, 或 Shiro 这样安全框架提供, 我们的代码不⽤直接处理这些事情. 3. 利⽤ Session, 可以衍⽣出更多的功能, ⽐如保存访客上次访问的 IP 和上次访问时间, ⽐如保存 user Id 和 user name, 这⾥稍微要多想⼀下:
(1). 这些数据既可以保存到 DB 中, 也可以保存到 Session 内存中, user id 和 user name 在 DB 中本来就保存着, 有必要在 session 中保存吗?
Session 的优点是访问速度快, 缺点是⽤户量⼤的情况下内存占⽤是个问题.
(2). 这些数据既可以保存到 cookie , 也可以保存到 Session 内存中, 哪个更适合?
Cookie 的优点是: 不占⽤服务器端内存, Session 占服务器内存并且重启后就没了, cookie 可以被js访问到, 常⽤的⽹页埋点就是把⼀些标记信
息保存到cookie, 然后由js提交到埋点服务器中. Cookie 的缺点是, cookie 数据如果较⼤, 会消耗较多的⽹络带宽; ⽤户随意修改 cookie 值, 这样的话, cookie的数据就不太可靠了; 另外, ⽤户
换个浏览器或者浏览器清个缓存, 原有的cookie就没法⽤了.
这些问题都没有标准答案, 按照具体情形做选择吧.
===================================
JSESSIONID Cookie 是到底是在什么时候⽣成?
===================================
JSESSIONID Cookie 并不是在第⼀次访问⽹站时候⽴即⽣成的, 只有访问 url 对应视图函数中有 Session 相应操作时, 浏览器端才会创建
JSESSIONID cookie 的.
当然, ⼀般⽹站在⾸页访问的视图函数基本都会有 session 操作, 所以给我们的错觉是, ⼀旦新访问⼀个⽹站, JSESSIONID cookie 就⾃动产
⽣了.
// 该 url 请求没有任何与 session 相关的操作, 浏览器端不会创建该⽹站的 JSESSIONID cookie@GetMapping("/")public String index(HttpServletRequest request) throws SQLException { return "OK";}
// 在 url 请求中, 有获取 session 对象的指令, 浏览器端会创建该⽹站的 JSESSIONID cookie@GetMapping("/")public String index(HttpServletRequest request) throws SQLException { request.getSession(); //获取 session 对象 return "OK";}
// 在 url 请求中, 视图函数要注⼊ session 对象, 浏览器端会创建该⽹站的 JSESSIONID cookie@GetMapping("/")public String index(HttpSession session) throws SQLException { return "OK";}
===================================
JSESSIONID 的 ID 值会登录后会变化吗?
===================================
假设在登录之前, 浏览器端已经有了 JSESSIONID cookie. 现在问题来了, 在⽤户登录之后, 该 JSESSIONID ID 值是否变化?
答案是: 早期⽹站, 登录前后 JSESSIONID 是不变的, 但后来发现, 如果登录前后 JSESSIONID 不变, 会有中间⼈攻击风险. 所以现在的安全框
架在登录完成后, 会⾃动修改 JSESSIONID 值. 我们开发⽹站不需要再专门修改 JSESSIONID.
和登录不⼀样, 登录退出 JSESSIONID 的 Id 值并不会改变.===================================
Session 和 cookie 之间的关系?
===================================
前⾯已经提到为了标识同⼀个客户端访问, 光靠服务器端的 Session 是不够的, 还需要客户端 JSESSIONID Cookie ⽀持. 这体现了 Session
和 cookie 之间最重要的⼀个关系.
另外, 在 Web 开发中 Session 和 Cookie 有⼀些很类似的⽅法, 往往会引起混淆, 有必要区别⼀下. 1. Session:
保存在服务器端内存中, 服务器重启所有的 session 都没了.
session.setAttribute() 是在服务端内存中保存⼀个属性, 并不会将它保存到浏览器端的 Cookie 中.
可以在⼀个 session id 下新建多个属性.session 的有效期是针对所有 session id 全局级别的, 不是单个 session id 级, 也不是属性级的.
Session 中 id 和对应的属性, 可以⼤致理解为从属关系, 这些属性属于⼀个 id.2. Cookie:
保存在浏览器本地存储中, 服务器重启并不会影响 cookie.
⼀个⽹站下可以包含多个 cookie , 最重要的那个是 JSESSIONID Cookie. 新建⼀个 cookie 并不会在服务器端⽣成⼀个对应的属性.
每个 cookie 都可以设置⾃⼰的有效期, ⾃⼰的 HttpOnly 属性.
⼀个⽹站的 JSESSIONID Cookie 和其他 cookie 并没有从属关系
===================================
Spring 中 Session 和 cookie 的操作⽅式
===================================
Spring Session操作很简单:
//获取 session 对象, 或者视图函数中直接注⼊ HttpSession 对象request.getSession()
//设置⼀个 session 属性session.setAttribute()
//读取⼀个 session 属性
session.getAttribute()
1. 在视图函数中使⽤ @CookieValue 修饰形参, 可注⼊⼀个 cookie 属性值.
@RequestMapping("/read") @ResponseBody public String read(@CookieValue(value = "foo", defaultValue = "hello") String fooCookie) { System.out.println(fooCookie); return fooCookie; }
2. 使⽤ HttpServletResponse.addCookie() 完成 cookie 的写⼊.
@RequestMapping("/write") @ResponseBody public String write(HttpServletResponse response) { Cookie foo = new Cookie("foo", "bar"); //bake cookie foo.setMaxAge(1000); //set expire time to 1000 sec response.addCookie(foo); //put cookie in response return "write done"; }
==================================
SSO/JWT/Session/OAuth2和web项⽬安全检查的关系
==================================
1. OAuth2: 它是⼀个第三⽅认证机制, 适合To C的应⽤场景, ⽐如我们开发⼀个app, 可以借⽤微信/微博⽤户认证开放接⼝, 达到免注册登陆,
企业内部系统⼀般没必要引⼊该技术.2. SSO: 有两个作⽤, 1: 保持登陆状态, 2: 识别 username
3. JWT: 它是⼀个 token ⽣成技术, 可以包含 username 等信息.
4. Session: Session ⼀般⽤在web application中, ⽤来识别访问者.