目录
1、登录的过程
登录需要实现两个请求处理
第一次需要处理表单的内容,校验登录信息
第二次请求,会发送第一次请求的 token,需要处理这个 token,从而从登录页跳转到首页
2、验证码功能实现
在 SystemController 添加相应的方法
@RestController
@RequestMapping("/sms/system")
public class SystemController {
@GetMapping("/getVerifiCodeImage")
public void getVerifiCodeImage(HttpServletRequest request, HttpServletResponse response){
// 获取图片
BufferedImage verifiCodeImage = CreateVerifiCodeImage.getVerifiCodeImage();
// 获取图片上的验证码
char[] verifiCodeChars = CreateVerifiCodeImage.getVerifiCode();
String verifiCode = new String(verifiCodeChars);
// 将验证码文本放入session域,为下一次验证做准备
HttpSession session = request.getSession();
session.setAttribute("verifiCode", verifiCode);
try {
// 将验证码图片响应给浏览器
ServletOutputStream outputStream = response.getOutputStream();
// 将verifiCodeImage以JPEG的格式写到outputStream流中
ImageIO.write(verifiCodeImage,"JPEG",outputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、登录校验功能实现
3.1、在 service 及其实现类添加登录验证方法
AdminService
public interface AdminService extends IService<Admin> {
/**
* 登录校验,查询提交的表单是否有此人
* @param loginForm 登录页提交的表单
* @return
*/
Admin login(LoginForm loginForm);
}
AdminServiceImpl
@Service("adminServiceImpl")
@Transactional
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
/**
* 登录验证,查询提交的表单是否有此人
* @param loginForm 登录页提交的表单
* @return
*/
@Override
public Admin login(LoginForm loginForm) {
QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name",loginForm.getUsername())
// 注意将密码转为密文
.eq("password", MD5.encrypt(loginForm.getPassword()));
Admin admin = baseMapper.selectOne(queryWrapper);
return admin;
}
}
StudentService
public interface StudentService extends IService<Student> {
/**
* 登录校验,查询提交的表单是否有此人
* @param loginForm 登录页提交的表单
* @return
*/
Student login(LoginForm loginForm);
}
StudentServiceImpl
@Service("stuService")
@Transactional
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
/**
* 登录校验,查询提交的表单是否有此人
* @param loginForm 登录页提交的表单
* @return
*/
@Override
public Student login(LoginForm loginForm) {
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", loginForm.getUsername())
// 注意将密码转为密文
.eq("password", MD5.encrypt(loginForm.getPassword()));
Student student = baseMapper.selectOne(queryWrapper);
return student;
}
}
TeacherService
public interface TeacherService extends IService<Teacher> {
/**
* 登录校验,查询提交的表单是否有此人
* @param loginForm 登录页提交的表单
* @return
*/
Teacher login(LoginForm loginForm);
}
TeacherServiceImpl
@Service("teaService")
@Transactional
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements TeacherService {
/**
* 登录校验,查询提交的表单是否有此人
* @param loginForm 登录页提交的表单
* @return
*/
@Override
public Teacher login(LoginForm loginForm) {
QueryWrapper<Teacher> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", loginForm.getUsername())
// 注意将密码转为密文
.eq("password", MD5.encrypt(loginForm.getPassword()));
Teacher teacher = baseMapper.selectOne(queryWrapper);
return teacher;
}
}
3.2、controller 方法
SystemController
@RestController
@RequestMapping("/sms/system")
public class SystemController {
@Autowired
private AdminService adminService;
@Autowired
private StudentService studentService;
@Autowired
private TeacherService teacherService;
/**
* 验证码功能的实现
*
* @param request
* @param response
*/
@GetMapping("/getVerifiCodeImage")
public void getVerifiCodeImage(HttpServletRequest request, HttpServletResponse response) {
// 获取图片
BufferedImage verifiCodeImage = CreateVerifiCodeImage.getVerifiCodeImage();
// 获取图片上的验证码
char[] verifiCodeChars = CreateVerifiCodeImage.getVerifiCode();
String verifiCode = new String(verifiCodeChars);
// 将验证码文本放入session域,为下一次验证做准备
HttpSession session = request.getSession();
session.setAttribute("verifiCode", verifiCode);
try {
// 将验证码图片响应给浏览器
ServletOutputStream outputStream = response.getOutputStream();
// 将verifiCodeImage以JPEG的格式写到outputStream流中
ImageIO.write(verifiCodeImage, "JPEG", outputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 登录验证,查询提交的表单是否有效
* @param loginForm 登录页提交的表单
* @param request
* @return
*/
@PostMapping("/login")
public Result login(@RequestBody LoginForm loginForm, HttpServletRequest request) {
// 验证码校验
HttpSession session = request.getSession();
String sessionVerifiCode = (String) session.getAttribute("verifiCode");
String loginVerifiCode = loginForm.getVerifiCode();
if ("".equals(sessionVerifiCode) || null == sessionVerifiCode) {
return Result.fail().message("验证码失效,请刷新后重试");
}
if (!sessionVerifiCode.equalsIgnoreCase(loginVerifiCode)) {
return Result.fail().message("验证码错误");
}
// 从session中移除现有验证码记录
session.removeAttribute("verifiCode");
// 对用户类型进行校验
Map<String, Object> map = new LinkedHashMap<>(); // 用于存放响应的数据
switch (loginForm.getUserType()) {
case 1:
try {
Admin admin = adminService.login(loginForm);
if (null != admin) {
// 在数据库找到该用户,将用户类型和用户id转换为密文,以token向客户端返回信息
map.put("token", JwtHelper.createToken(admin.getId().longValue(), 1));
} else {
throw new RuntimeException("用户名或密码错误");
}
// 若没有异常,说明可以登录,返回结果
return Result.ok(map);
} catch (RuntimeException e) {
e.printStackTrace();
// 产生异常,返回出错信息
return Result.fail().message(e.getMessage());
}
case 2:
try {
Student student = studentService.login(loginForm);
if (null != student) {
// 在数据库找到该用户,将用户类型和用户id转换为密文,以token向客户端返回信息
map.put("token", JwtHelper.createToken(student.getId().longValue(), 2));
} else {
throw new RuntimeException("用户名或密码错误");
}
// 若没有异常,说明可以登录,返回结果
return Result.ok(map);
} catch (RuntimeException e) {
e.printStackTrace();
// 产生异常,返回出错信息
return Result.fail().message(e.getMessage());
}
case 3:
try {
Teacher teacher = teacherService.login(loginForm);
if (null != teacher) {
// 在数据库找到该用户,将用户类型和用户id转换为密文,以token向客户端返回信息
map.put("token", JwtHelper.createToken(teacher.getId().longValue(), 3));
} else {
throw new RuntimeException("用户名或密码错误");
}
// 若没有异常,说明可以登录,返回结果
return Result.ok(map);
} catch (RuntimeException e) {
e.printStackTrace();
// 产生异常,返回出错信息
return Result.fail().message(e.getMessage());
}
}
return Result.fail().message("查无此用户");
}
}
4、登录校验后从登录页跳转到首页
4.1、完成 service 方法及其实现类
AdminService
/**
* 根据用户id查找用户
* @param userId
* @return
*/
Admin getAdminById(Long userId);
AdminServiceImpl
/**
* 根据用户id查找用户
* @param userId
* @return
*/
@Override
public Admin getAdminById(Long userId) {
Admin admin = baseMapper.selectById(userId);
return admin;
}
StudentService
/**
* 根据用户id查找用户
* @param userId
* @return
*/
Student getStdentById(Long userId);
StudentServiceImpl
/**
* 根据用户id查找用户
* @param userId
* @return
*/
@Override
public Student getStdentById(Long userId) {
Student student = baseMapper.selectById(userId);
return student;
}
TeacherService
/**
* 根据用户id查找用户
* @param userId
* @return
*/
Teacher getTeacherById(Long userId);
TeacherServiceImpl
/**
* 根据用户id查找用户
* @param userId
* @return
*/
@Override
public Teacher getTeacherById(Long userId) {
Teacher teacher = baseMapper.selectById(userId);
return teacher;
}
4.2、完成 controller 方法
根据请求参数 token 中的信息,传输用户信息给客户端
/**
* 根据登录第二次请求发送来的token,传送用户信息回去
* @param token
* @return
*/
@GetMapping("/getInfo")
public Result getInfoByToken(@RequestHeader("token") String token){
// 判断token是否过期
boolean expiration = JwtHelper.isExpiration(token);
if(expiration){
// 过期,返回错误信息
return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
}
// token没有过期,解析出用户id和用户类型
Long userId = JwtHelper.getUserId(token);
Integer userType = JwtHelper.getUserType(token);
// 向map中传入数据
Map<String, Object> map = new LinkedHashMap<>();
switch (userType){
case 1:
Admin admin = adminService.getAdminById(userId);
map.put("userType", userType);
map.put("user", admin);
break;
case 2:
Student student = studentService.getStdentById(userId);
map.put("userType", userType);
map.put("user", student);
break;
case 3:
Teacher teacher = teacherService.getTeacherById(userId);
map.put("userType", userType);
map.put("user", teacher);
break;
}
return Result.ok(map);
}
5、解决登录后用户头像错误问题
如下图,用户头像加载错误
通过控制台,可以很容易的发现该图片的存放地址,只需将图片放入对应的目录下即可
完成后即可看到头像