今天来说一下Cookie和Session,以及他们工作方式和原理…,但是说这两之前,我还想提一个新的东西-------form表单。
form表单
form同步提交的方式:提交数据之后一定会跳转页面。以后我们再说一些异步提交的方式。
<!--action配置走哪个servlet接口,method配置走的请求方式-->
<form action="login" method="post">
<!--from表单,其代表的是将from中包含name属性的标签的value值作为将要发送到服务器上的一个属性的整合标签-->
用户名:<input type="text" name="username">
<!--input代表一种页面输入行为,其中属性type描述了这个输入行为是以一种什么样的展示形式来获取用户输入-->
<!--name属性一般来说没有任何作用,他的作用是在准备提交数据的时候,表示这个数据的key值-->
密码:<input type="password" name="pwd">
<input type="submit" value="登陆">
</form>
Cookie
- 小饼干,HTTP定义的一种由浏览器保存临时数据的形式(cookie处理内容的过程有两种,一种是对后台(Java),一种是前端(js))
- Cookie保存内容的形式是k-v对,一般是 <k,v> 对形式来保存内容的。
- 每次浏览器发出请求的时候,都会将自己的cookie发送给后台,有多少,发多少,后台如果想要设置让前端保存什么内容的话,会通过set-Cookie头来通知前端保存内容.
1、在控制台中Application中找到并调试Cookie
2、后端设置Cookie:
Cookie cookie = new Cookie("username", username);
resp.addCookie(cookie); //将设置好的Cookie返回给浏览器
3、浏览器添加Cookie的过程
- 首先我先访问 login ,在这个servlet中会设置一个Cookie并返回给浏览器。
- 跳转到success.html之后:
4、前端获得Cookie的过程。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
欢迎回来:<span id="username"></span>
</body>
<!--前端获得cookie内容的过程-->
<script type="text/javascript">
//弱类型语言,获得浏览器地址的语句是
var u = document.cookie.split("; ");
for(var i = 0; i < u.length; i++){
if(u[i].startsWith("username")){
document.getElementById("username").innerText = u[i].split("=")[1];
}
}
//向目标点加入内容
//document:从头到尾 getElementById: 遍历获取id的内容
</script>
</html>
5、Cookie的常用方法
- Cookie设置生效域:
cookie.setDomain("qq.com"); //说明此Cookie只在"qq.com"下生效
- Cookie设置生效路径:
cookie.setPath("/user/index"); //说明此Cookie只在"/user/index"路径下生效
这里注意:访问此路径下的URL可以看到Cookie的值,否则就会看不到的,
当你到/web/index之下两个Cookie都可以看到,但是如果你只到了/web下的话,那么只能看到一个Cookie。
- Cookie设置生效时间:
cookie.setMaxAge(10) //10代表10s
- 后端拿到前端发过来的Cookie:
Cookie[] cookies = req.getCookies(); //拿到的一定是个Cookie数组,从数组中可以筛选条件,找到想要的Cookie
for(Cookie c : cookies) {
System.out.println(c.getName() + " : " + c.getValue());
}
注意Cookie不好的地方:
在一些只有登录之后(或者用Cookie做一些判断是否符合条件的情况下)才能做一些动作的场合如果用了Cookie的话,非常不安全,因为在Application中可以修改Cookie,让服务器误以为已C经符合条件了,这就是很可怕的了。比如你只有登录之后才能做的事,别人知道你的用户名之后,直接在Application加上一条Cookie,这时你登录和密码的过程不就形同虚设了吗?对吧,所C以说Cookie是不安全的。
这个过程叫做CFRF攻击:
- 错误使用Cookie或者过分依赖Cookie,
- HTTP是一种无状态的协议,也就是说HTTP是不能记录用户状态的什么是无状态:所谓的无状态,就是说一个浏览器第一次和第二次发出的请求,服务器是没有办法分辨的,但是我们知道HTTP是基于TCP实现的,为什么会出现无状态呢,因为TCP是有状态的,比如连接建立之后这个连接就是一种状态,如果登陆了,也就是说,这个连接都登陆成功了。
- 为什么?:因为HTTP是短链接,HTTP基于TCP不假,但是HTTP是连接,数据传输,断开这个时候,TCP已经断了,所以下一次HTTP是一个新的HTTP请求,所以我们说HTTP是无状态的
- 但是我们有时候确实需要HTTP协议在前端记录一些内容,来模拟HTTP的状态,这个时候,我们就可以使用一种叫做Cookie的东西来实现这个过程。
- 所以Cookie是不可信的,如果将很重要的信息保存在Cookie中的话,就会对后台产生很大的业务影响。
- Cookie中记录的值,都是一些无关紧要的值,或者不容易被修改的值。
Session
为了解决HTTP的无状态的特性,我们引入了Cookie,为了解决Cookie的不可信问题,我们引入了另一个关键的信息,叫做Session。
- Cookie的缺点就是写在了前端,里面记录的KV对是不可信的,也就是说,如果我们把内容保存在后台,就会OK的,信息绝对安全保密。
Session就是保存在后台的一种KV对的存储结构,但是其保存过程又要和前端保持一致,所以我们设计Session的时候,将其保存的内容格式设计成 <Y,<K,V>> 。
也就是说,最外层的Y是一个ID值,它保存在Cookie中,他的值是一个32位的16进制数(永远不会重复),发给前端,这个Y对应了另一个Map结构,这个Mao里面保存着持有Y的ID的前端所记录的所有状态。
Session的常用方法
- 后端设置Session
HttpSession session = req.getSession();
session.setAttribute(String s, Object o); //将设置的KV对信息发送给前端
- 后端获取Session的值
HttpSession session = req.getSession();
String name = session.getAttribute("username"); //获取username的value值。
Tomcat规定的SessionID有效时间只有半个小时,意味着半个小时去破解基本是不可能的。
- 设置Session失效
HttpSession session = req.getSession();
session.invalidate();
- 获取所有Session的Key值
HttpSession session = req.getSession();
session.getAttributeNames();
- 设置Session最大有效时间
HttpSession session = req.getSession();
session.setMaxInactiveInterval(int i); //秒级别