饼干是什么
我们都知道,浏览器与WEB服务器之间一般是使用HTTP协议来进行通信的。但是这个HTTP协议是一个无状态的协议。
协议的状态:下一次传输可以”记住“这一次传输信息的能力。
无状态就是这次我从浏览器向某服务器发送一次请求,服务器响应了。当再用该浏览器向该服务器发请求的时候,它当你是一个全新请求,跟前一次,前前一次,后一次,什么时候的请求都没关系。它不“记得”你上一次的登录了。也就是同一个会话的连续两个请求其实对协议来说是毫无关系的。
。无状态的协议对我们有什么影响呢有这么一个场景:
用户在淘宝登录页面填写账号与密码后,点击登录,这时触发了一个HTTP请求:https://*.*.*/logon。
然后它选中“手机频道”点击进去,这时又会触发了一个HTTP请求:https://*.*.*/phone。
进入到手机频道的页面后,我们会发现“我的淘宝”里显示我的账号还在登录。
因为后一次的HTTP请求跟前一次的请求是没关系的,所以如果后一次请求不告诉服务器账号和密码,服务器是不会知道账户是谁的。那么要实现上面的情况,只能是在后一次请求的时候把账号和密码再传过来,服务器再验证一次。
如果往后的所有请求都要带着账号和密码给服务在处理真正业务前先验证,那么这个重复劳动有多累人。万一哪个程序员在写某个HTTP请求的时候忘了传账号和密码,那不是每次到它这个请求的时候都登不上去。
所以Cookie出现了。
Cookie是一种通过请求和响应报文中写入Cookie信息来控制客户端状态的技术。服务器的响应信息中可以带上想要客户端保存的信息,让客户端每次请求的时候自动带上,这就是Cookie。
Cookie是如何在整个流程中动作的
1.客户端(比如一个浏览器)第一次向服务器请求的时候(比如登录),是没有Cookie的。
2.服务器收到客户端请求后,会将用户登录信息设置为Cookie返回给客户端。
3.客户端收到返回信息和其中的饼干,它会将Cookie的解析并保存起来。
4.再次发送请求的时候,它会将Cookie的信息带上。
5.服务器解析曲奇并取得其中的信息,与后台的用户信息对比,对比正确说明该用户已登录。
...
Java示例:
包com.hlm.controller;
import java.util.HashMap;
import java.util.Map;
import javax.management.RuntimeErrorException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.hlm.command.UsersCommand;
@Controller
公共类UsersController {
/ **
*保存用户登录信息
* /
public Map <String,String> logonMap;
/ **
*用户登录
* @param req
* @param mv
* @返回
* /
@RequestMapping( “/登录”)
public ModelAndView logon(HttpServletRequest req,HttpServletResponse resp){
ModelAndView mv = new ModelAndView();
UsersCommand cmd = new UsersCommand(“小明”,0,“[email protected]”,1,“123456”);
mv.addObject(“password”,cmd.getPassword());
mv.addObject(“userName”,cmd.getUserName());
的System.out.println(cmd.getPassword());
mv.setViewName( “/登录”);
//设置Cookie返回给浏览器保存
resp.addCookie(新Cookie(“userName”,cmd.getUserName()));
resp.addCookie(新的Cookie(“密码”,cmd.getPassword()));
//后台保存对应的登录信息
如果(logonMap == NULL){
logonMap = new HashMap <String,String>();
}
//保存经过转换后的信息
logonMap.put(cmd.getUserName()+ cmd.getPassword(),cmd.getPassword()+ cmd.getUserName()+“123456789”);
返回mv;
}
/ **
*登录后其他操作
* @param req
* @param mv
* @返回
* /
@RequestMapping( “/欢迎”)
public String getOther(HttpServletRequest req){
//从Cookie中获取用户登录信息
Cookie [] cookies = req.getCookies();
String userName =“”;
String password =“”;
for(Cookie e:cookies){
如果( “username” 的.equals(e.getName())){
userName = e.getValue();
} else if(“password”.equals(e.getName())){
password = e.getValue();
}
}
//查询是否与后台保存的登录信息对应
String token = logonMap.get(userName + password);
if(token == null || token.trim()。length()== 0){
抛出新的RuntimeErrorException(null,“用户未登录!”);
}
if(!token.equals(password + userName +“123456789”)){
抛出新的RuntimeErrorException(null,“用户登录已失效!”);
}
返回“welcome.html”;
}
}
Controller中有两个方法,一个是登录,一个是登录后的其他操作。
登录方法中将用户的登录名和密码放于Cookie中返回请浏览器保存,用于下次请求。
登录后的其他操作方法中,从请求中取出Cookie的用户登录信息并记录在服务器的已登录信息对比,存在并正确则让它进入页面,否则抛异常。
先进首页:
点击连接,触发登录
然后,我要进入其他页面
成功进入,说明后台校验通过,说明Cookie生效了。
下面我再演示,浏览器禁用Cookie的后的情况。
进入首页
登录
进入用户专用页面
看后台Cookie是空的