今天小祥去一家十八线互联网公司面试,结果被一个问题问死了
(靓仔叹气)
填完应聘信息后,人群中窜出一个光头给我带进了会议室开始面试
光头哥拿着简历:“你先做个自我介绍吧。”
我:“巴拉巴拉。。。”
光头哥突然眉头一皱:“你做过单点登录?”
我:“对,基于redis做的”
光头哥:“具体是怎么实现的?”
我:“就是在登录A系统成功后将token和用户信息存进redis中,之后再登录B系统的时候去cookie中获取对应的信息。如果存在就去SSO的认证接口认证token是否正确 SSO系统根据token凭证(SSO系统去redis校验是否有值 有值就更新redis的缓存时间和传统session 一样的原理)来判断返回给B系统对应是否成功的表示。如果有就直接跳转。没有就去登录页面。”
光头哥:“嗯,你们是用到了cookie,如果cookie禁用了怎么办呢?”
我挠了挠头,脑子在疯狂跳托马斯:“emmm,我不清楚。”
光头哥:“那换个问题,cookie禁用了,session还能用吗?”
我陷入了知识盲区:“。。应该不能。”
光头哥乘胜追击:“为什么不能呢?”
后面就没怎么聊等通知了…
我们来好好了解下cookie和session
1.cookie是什么?
在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
2.session是什么?
session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。
3.总结下cookie和session的区别
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。 - session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用cookie。 - 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
- 所以小祥建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
4.cookie禁用了session还能用吗?
在默认的JSP、PHP配置中,SessionID是需要存储在Cookie中的,默认Cookie名为:
PHPSESSIONID
JSESSIONID
以下以PHP为例:
你第一次访问网站时,
服务端脚本中开启了Sessionsession_start();,
服务器会生成一个不重复的 SESSIONID 的文件session_id();,比如在/var/lib/php/session目录
并将返回(Response)如下的HTTP头 Set-Cookie:PHPSESSIONID=xxxxxxx
客户端接收到Set-Cookie的头,将PHPSESSIONID写入cookie
当你第二次访问页面时,所有Cookie会附带的请求头(Request)发送给服务器端
服务器识别PHPSESSIONID这个cookie,然后去session目录查找对应session文件,
找到这个session文件后,检查是否过期,如果没有过期,去读取Session文件中的配置;如果已经过期,清空其中的配置
如果客户端禁用了Cookie,那PHPSESSIONID都无法写入客户端,Session还能用?
答案显而易见:不能,并且服务端因为没有得到PHPSESSIONID的cookie,会不停的生成session_id文件。
5.cookie禁用了怎么办?
禁用Cookie之后,那么我们的jsessionid就不能在浏览器中保存,那么后面的请求中就不会将jsessionid发送到服务器,服务器这面就找不到数据
要解决这个问题我们可以采用URL重写的方法。
1.手动拼接jsessionid
// session对象
HttpSession session = req.getSession();
// 获取jsessionId
String jsessionid = session.getId();
// 设置共享数据
session.setAttribute("name", name);
//------------------------------------------------------
writer.print("欢迎"+name+"<br/>");
writer.print("<a href='/session/list;jsessionid="+jsessionid+"' >你好</a>");
2.使用响应对象HttpServletRequest中的encodeURL(String path)拼接jsessionid
// session对象
HttpSession session = req.getSession();
// 设置共享数据
session.setAttribute("name", name);
//------------------------------------------------------
writer.print("欢迎"+name+"<br/>");
String url = resp.encodeURL("/session/list");
System.out.println(url);
writer.print("<a href='"+url+"' >你好</a>");
这波你学废了吗?小祥是要继续好好准备面试了!