一.单一的java项目的登陆记录 –>作为单点登陆的参考基本解决方案
-->实际做过的小项目较多 这种就没啥好说的了
a.登入请求 request.setSession("userName",userName); 并设置session超时时间
b.使用loginfilter拦截所有非登入的请求,通过session(sessionId更准确)确认登陆状况
另外,loginfilter-->session-->sessionId-->cookie 依次依赖
http无状态请求request,客户端要保存有状态的数据就得有别的东西-->cookie,cookie中就包含了sessionId,
cookie中的sessionId是第一次请求时服务端生成的,然后response返回浏览器端,浏览器端进行保存,
再次请求时request中会携带cookie
servlet容器(tomcat)可以通过sessionId得到session对象,服务端在session对象存储一些数据
--> 依靠服务端存储登陆数据
HttpSession session = request.getSession();
session.setAttribute("name", "xxxx");-->通过session存放数据
session.setAttribute("psd", "xxxx");
session.setAttribute("otherxxx", "xxxx");
session.setMaxInactiveInterval(60*60);
所以用session记录登陆状态,本质上来说也是强依赖cookie
二.单点登陆不同场景
多服务下才需要单点登陆,而服务整体对外暴露的就是域名,所以我们以域名为切入点分析不同场景
1. 同一域名不同站点 (共享同一个主机地址)music.baidu.com/songlist music.baidu.com/mall
此种情况同单一服务的并没有多少区别,
同一域名下不同子域 比如百度.com下 zhidao.baidu.com news.baidu.com
a.按照单机项目的逻辑,依照sessionId取session–>依靠服务端存储登陆数据
但有个问题sessionId在多域名下不共享
原因是cookie在不同域名下是不共享的 –> 设置cookie的作用域domain + path 为baidu.com + /,变成二级域名所有路径(规范禁止了设置成顶级域名),则各子域间可以共享
cookie.setDomain(".baidu.com"); cookie.setPath("/"); 登陆服务 request(浏览器端看):Cookie:JSESSIONID=1603588F741AF4262A0F821C8E01006F path:/
于是cookie已经在同一二级域名下共享了
则sessionId共享了
–>but即便共享了sessionId,实际请求的时候呢,发现其他服务仍旧自己生成新的request,虽然也可以取到该共享的sessionId
服务2 request:Cookie:JSESSIONID=1603588F741AF4262A0F821C8E01006F; path:/ -->登陆服务产生的共享sessionId 如果不设置domain+path这里是不会有的 JSESSIONID=1EAFEF7CE59243FFE53FDC23B03C270B; path:/wenching-Demo/user(服务2的站点) -->第一次请求服务2时新产生的 服务自产的 通过request.getSession()获取到的是服务2自己产生的session
所以产生了问题? 改动挺复杂的
a.1 怎么取共享的sessionId? 又或者说怎么区分两个JSESSIONID ——>没好思路 a.2 sessionId即便取到了,如果取session里的内容 -->需要独立部署redis之类的存放sessionId和session信息 完成session共享
b.原路不通,换–>直接在浏览器端存储
cookie已经可以共享了,但数据不一定非得存在sessionId然后去服务器取,可以直接存在浏览器端
登陆服务
Cookie nameCookie = new Cookie("name", "zxw");//新建名为name的cookie nameCookie.setDomain(".baidu.com");//设定这个cookie的作用域 nameCookie.setPath("/"); Cookie psdCookie = new Cookie("psd", "ddddd"); psdCookie.setDomain(".baidu.com"); psdCookie.setPath("/"); response.addCookie(nameCookie);//写到浏览器 response.addCookie(psdCookie); //依照name and psd判断 并将数据存入自己的session
服务2
Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { String name = cookie.getName(); if("name".equalsIgnoreCase(name)){ System.out.println("name = " + cookie.getValue()); }else if("psd".equalsIgnoreCase(name)){ System.out.println("psd = " + cookie.getValue()); }else if("JSESSIONID".equalsIgnoreCase(name)){ System.out.println("JSESSIONID = " + cookie.getValue()); response.setHeader("Set-Cookie", "isVisit=true;domain=.127.0.0.1;path=/;max-age=1000"); } } //依照name and psd判断 并将数据存入自己的session
问题似乎解决了,but cookie存储的弊端又来了
b.1 浏览器端存数据不安全 ——>加密/设置有效期 即便被抓取了,也是密文,又有有效期限制 b.2 cookie可能被用户禁用-->有很多网站是强制用户开启cookie功能的 比如百度 b.3 cookie存储数据有限 4K左右 cookie个数也有限制 -->硬性限制 所以尽量存少量数据
不同域名 baidi.com csdn.com
不同二级域名,更加的凸显了cookie的跨域问题,因为场景2的cookie设置无效了
二.不同实现
实质上就是将代码转了一种格式,跟内存完全没有关系,只是类似把中文翻译成英文,java代码翻译成字节码