简介
Cookie和Session在web安全中常常被利用,大家肯定听过Cookie存储在浏览器中,而Session存储在服务器中。但是怎么个存法,被如何利用,什么时候能被利用,想必未从事过开发的朋友很多都是云里雾里,这篇文章从源码角度透析两大应用。
Session
浏览器关闭重写打开,Session会被重新刷新。
1.浏览器在访问服务器时,会自己先生成一个JSONSESSION,当我们访问某一个网站时,有一个Session在请求包的载荷中。
从请求标头中能发现:浏览器自己设置了Session的值,因为服务器此时并未设置Session
接下来,我们在JAVA服务端定义Servlet类,并且处理请求中的Session值,将其作为键值对储存在服务端。
首先我们先简单看一下按下登录键后,触发的request请求的参数。
axios.post("/student/login",this.ruleForm).then(resp=>{
if(resp.data=="Success"){
this.$message({
message:'恭喜你,登陆成功',
type:'success'
});
setInterval(function (){
location.href="../index.html";
},1000);
}//该部分是点击登录后,如果后端返回Success进行跳转的代码
//下面是request传递的参数
ruleForm: {
stuId: "",
password: "",
state: true
}
2.服务器端获取Session,并且设置Session的键值对存储在本地文件里
@WebServlet("/student/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader br=req.getReader();//获取请求的post
String LoginDate = br.readLine();//将post请求数据存储为字符串
LoginDate loginDate = JSON.parseObject(LoginDate, LoginDate.class);//利用JSON格式解析字符串存出为LoginDate对象。
ServicePro servicePro=new ServicePro();
Student student=servicePro.Login(loginDate);//这里的函数是检验获取的参数在数据库中是否存在。
if(student!=null){
//存在则获取Session
HttpSession session = req.getSession();
//loginDate.getStuid(),获取loginDate对象中的stuid为相应的request参数
session.setAttribute("stuid",loginDate.getStuid());//设置Session的属性,Session为 stuid是key,loginDate.getStuid()是map值
resp.getWriter().write("Success");
}
else{
resp.getWriter().write("Fail");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
后端代码获取到Session后,对其设置属性。方便下次访问时,获取用户发来的Session,再通过Session值获取到stuid值。
可以理解为:
session值->key(这里是"stuid")->value(这里是"stuid"的值)。
3.服务端在其他页面中被访问后,获取请求端的Session,通过Session的key获取Value,然后使用Value确定该页面被操作的用户。
我们从开发角度看获取Session的用处:
利用获取的Session值,获取到用户的关键信息,这个信息一般是是数据的主键(唯一且非空),就能通过session找到主键值,再利用主键值就方便提取用户的有关信息了。
HttpSession session = request.getSession();
String stuId = (String) session.getAttribute("stuId");
Session安全问题
打开另外一个浏览器,将刚刚浏览器的Session复制到该浏览器的Session中进行请求,发现请求页面为刚刚浏览器的用户。
这个是登录后的页面
修改Session后,页面访问不加载该用户的课程
打开另外的浏览器
修改Session为谷歌浏览器的session值
加载该浏览器页面
该实验指出:如果Session被黑客获取则你有的用户就会被黑客随意操控!
Cookie
现在使用Cookie的越来越少,因为不安全,其存储数据在浏览器上。
1.Cookie在使用中是被存储在浏览器中的,却是由服务器端进行生成。
如果是第一次访问网站,是不会发送Cookie的(会有个JsessionID为Session)。但是一旦服务器设置了Cookie,下次访问网站时则会自己添加服务器设置的Cookie发送请求包。
后端代码对Cookie进行设置属性的过程,
public class LoginDate {
int stuid;
String password;
boolean state;
}//这个是LoginDate类
大家先记住有这个类,方便下面阅读代码
BufferedReader br=req.getReader();
String LoginDate = br.readLine();//前两句可以暂时理解为获取请求数据中的post值
LoginDate loginDate = JSON.parseObject(LoginDate, LoginDate.class);
//将post数据包中的json数据转为loginDate对象,因为该后端代码对应的是登录页面
ServicePro servicePro=new ServicePro();
Student student=servicePro.Login(loginDate);//上面两句代码为调用函数检验登录的账号是否正确,如果没有理解前面的代码可以自行跳过,下面为设置Cookie
if(student!=null){
if(loginDate.isState()){
//loginDate.getPassword()为获取登录数据中的password成员值
Cookie cookie_pass=new Cookie("password" ,loginDate.getPassword());
//password为key,loginDate.getPassword()获取的值为value组成了Cookie的键值对(属性)
cookie_pass.setPath("/web/student");//Cookie在当前网站中的路径作用范围,如果小于该范围则Cookie不会在客户端使用。
Cookie cookie_stuid=new Cookie("stuid",String.valueOf(loginDate.getStuid()));
cookie_stuid.setPath("/web/student");//这里设置了Stuid的Cookie键值对
cookie_pass.setMaxAge(60*60);//设置在浏览器的Cookie储存时间
cookie_stuid.setMaxAge(60*60);
resp.addCookie(cookie_pass);//添加Cookie在返回数据包中
resp.addCookie(cookie_stuid);
}
2.Cookie存储形式是键值对
演示:
注意事项:
Cookie使用是有有效路径的,并且需要设置Cookie的存活时间。