实际上,登录在逻辑上应该是”查询”操作,但是我们通常用post方法. 我们登录的结果(后端给前端返回的)往往有以下信息,我们可以封装成一个类.
/**
* 封装登录的结果
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginInfo {
private Integer id;
private String username;
private String name;
private String token;
}
其中token是后端给前端的令牌.我们后面再说.
controller层
/*
登录Controller
*/
@Slf4j
@RestController
public class LoginController {
@Autowired
private EmpService empService;
/**
* 登录方法
*@return 登录结果
*/
@PostMapping("/login")
public Result login(@RequestBody Emp emp){
log.info("登录请求,参数:{}", emp);
LoginInfo info = empService.login(emp);
if (info == null) {
return Result.error("用户名或密码错误");
}
log.info("登录成功,用户信息:{}", info);
return Result.success(info);
}
}
注意,由于Emp当中描述了员工的信息(包括用户名密码头像等等等等一系列信息),虽然前端只会传username和密码,但是还是可以正常接受的.
Service层
@Override
public LoginInfo login(Emp emp) {
//1.调用mapper查询员工信息
Emp e = empMapper.selectByUsernameAndPassword(emp);
//2.判断员工是否存在
if(e!=null){
log.info("登录成功,员工信息: {}", e);
return new LoginInfo(e.getId(),e.getUsername(),e.getName(),"");
}
return null;
}
token我们暂时不填.
mapper层
/*
* 根据用户名和密码查询员工信息
*/
@Select("select id, username,name from emp where username = #{username} and password = #{password}")
Emp selectByUsernameAndPassword(Emp emp);
当然,上述方案是有问题的,因为前端完全可以直接访问域名/XXX 来访问页面,而根本不需要通过域名/login
本质上,我们为了解决这个问题,就需要在用户访问后台主页面的时候进行登录校验,必须处于登录状态才能操作.
后端存储一个
登录标记
,记录当前时刻有哪些用户处于登录状态. 在用户访问后端任何一个Controller服务之前,要先把请求发送给一个
统一拦截
的网关.网关会检验每个请求,是否有对应的登录标记.如果有,那么就放行.如果没有,那么就直接给前端返回信息要求重新登录.
用户打开浏览器,访问web服务器的资源,会话就建立了.有一方断开连接,会话就结束了.在一次会话中间,可以包括很多次的请求和相应.
一种用来让服务器识别多次请求是否属于同一个浏览器的技术,这是用来在同一次会话的多次请求之间共享数据用的. 会话跟踪很重要.比如,如果需要在每次登录时使用验证码,这个验证码是需要后端传递给前端的.后端需要记住这次给前端传递了些什么,因为待会用户点击”登录”时会把这个验证码传给后端,后端需要把传来的验证码和之前记住的验证码进行比对.

三个自动: 比如第一次请求了登录接口,登录接口执行完成之后,我们就可以设置一个cookie,在 cookie 当中我们就可以来存储用户相关的一些数据信息。比如我可以在 cookie 当中来存储当前登录用户的用户名,用户的ID。 服务器端在给客户端在响应数据的时候,会自动的将 cookie 响应给浏览器,浏览器接收到响应回来的 cookie 之后,会自动的将 cookie 的值存储在浏览器本地。接下来在后续的每一次请求当中,都会将浏览器本地所存储的 cookie 自动地携带到服务端。

访问/c1直接就能让浏览器得到这个cookie. 访问/c2就会把cookie发到服务器. 可以查看本地存的cookie: 前三个都是与idea有关的,第四个是我们设置的. 另外,访问同一个网址的时候,会把网址对应的所有的cookie都发过去