1.1 业务分析
我们希望在访问后台页面时,先要进行登陆,再访问。
1.2 Entity对象设计
创建一个User类,基于此类存储用户信息。
@Data
public class User {
private Integer id;
private String username;
private String password;
private String nickname;
}
1.3 Mapper对象设计
@Mapper
public interface UserMapper {
@Select("select id,username,password,nickname from user where username=#{username}")
User selectByUsername(String username);
}
1.4 Controller对象设计
/**
* 定义用户数据请求处理的Controller对象
*/
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
//在参数列表里面声明session, 即可得到当前客户端所对应的Session(一个登录用户对应一个Session)
@PostMapping("/user/login")
public int login(@RequestBody User user, HttpSession session){
User u = userMapper.selectByUsername(user.getUsername());
if(u==null)return 2;//2表示用户不存在
//user代表用户输入的信息包括:用户名和密码
//u代表从数据库中查询到的信息 包括: id,用户名和密码,昵称
if(u.getPassword().equals(user.getPassword())){
//把当前登录的用户对象保存到会话对象中
session.setAttribute("user", u);
return 1;//表示密码正确
}
return 3;//表示密码不正确
}
@GetMapping("/user/currentUser")
public User currentUser(HttpSession session){
//获取登录成功时保存在session中的用户信息
return (User)session.getAttribute("user");
}
@GetMapping("/user/logout")
public void logout(HttpSession session){
//将登录成功时保存的用户信息移除
session.removeAttribute("user");
}
}
1.5 会话管理
-
客户端和服务器之间进行数据传输遵循的是HTTP协议 , 此协议属于无状态协议(一次请求对应一次响应 , 响应完之后链接就会断开) 服务器是无法跟踪客户端的请求 , 通过Cookie服务器可以给客户端添加一个标识 , 当客户端再次发出请求时会带着这个Cookie这样服务器就能识别此客户端了, 但是由于Cookie是保存在客户端的存在被篡改的风险 , Session的出现解决了此问题
-
Cookie : 打孔式会员卡 , 数据保存在客户端
- 只能保存字符串数据
- 默认数据是保存在浏览器内存中 , 当会话结束(浏览器关闭)数据会删除 , 也可以设置自定义的保存时长 , 设置完之后数据会保存在磁盘中时间到了之后清除
- 应用场景 : 需要长时间保存的数据 , 比如 : 记住用户名和密码
-
Session : 相当于银行账户 , 数据保存在服务器内存中(工程重新启动会清空所有Session)
- 可以保存任意对象类型的数据
- 默认数据只能保存半小时左右 , 而且不建议修改保存时长 , 因为数据是保存在服务器的内存中的 , 服务器只有一个所以不能占用太多的内存
- 应用场景 : 保存登录状态 , 涉及敏感数据 , 因为数据保存在服务器会更安全
1.6 Http访问测试
在resources目录中的http目录下创建文件user-api-test.http文件,并添加测试内容:
### 登录
POST http://localhost/user/login
Content-Type: application/json
{
"username": "admin",
"password": "123456"
}
### 获取登录后的用户信息
GET http://localhost/user/currentUser
### 移除登录状态
GET http://localhost/user/logout
1.7 登陆认证 - 过滤器
业务描述:
我们在访问后端的指定页面时,要判断用户是否登陆了,假如用户没有登陆不让直接访问后端页面,此时要跳转登陆页面,提示先登陆。代码实现:
第一步:定义过滤器,用于对指定url的访问检查登陆状态,例如:
/**
* 请求过滤器
*/
@WebFilter(filterName = "loginFilter",urlPatterns = {"/product/insert"})
public class LoginFilter implements Filter {
/**
* 当我们访问admin.html,insertBanner.html,insertProduct.html时,请求会被
* 当前过滤器拦截。
*/
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器执行了");
//1.获取HttpServletRequest,HttpServletResponse对象
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpServletResponse response=(HttpServletResponse) servletResponse;
//2.获取服务端的HttpSession对象
HttpSession session = request.getSession();
//3.从session对象中获取登陆user对象
User user=(User) session.getAttribute("user");
if(user==null){//假如这里为null,说明用户还未登陆,没有登陆则跳转到登陆页面
//response.sendRedirect("/login.html");
System.out.println("未登录!");
return;
}
//4.假如用户登陆了,则执行下一步操作(允许访问资源)。
filterChain.doFilter(servletRequest,servletResponse);
}
}
第二步:在启动类上添加@ServletComponentScan注解,用于对写的过滤器进行扫描,例如
//此注解的作用是在当前类所在的包以及子包下扫描过滤器
@ServletComponentScan
@SpringBootApplication
public class CoolsharkApplication {
public static void main(String[] args) {
SpringApplication.run(CoolsharkApplication.class, args);
}
}
第三步:对后端进行访问测试,检查未登陆前访问是否会跳转到登陆页面。
urlPatterns的配置方式
-
精确匹配 /admin.html /insertProduct.html
-
后缀匹配 *.jpg *.png *.html
-
路径匹配: /product/* /user/*
-
全部匹配: /* (客户端发出的所有请求都会被过滤器拦截)