项目实训——后端篇2:登录服务与注册服务

LoginController主要还是提供用户注册和登录的接口,并存储用户持续登录的信息。我们采用session来实现用户的保持登录状态

Session介绍

Session(会话)是服务器和客户端之间的一段互动时间,用于记录用户的状态和活动。在HTTP协议中,Session是一种解决无状态性问题的方法。每次HTTP请求都是独立的,但通过Session,可以将多个请求关联起来,形成连续的用户体验。

Session的工作原理

  • 创建Session:当用户第一次访问服务器时,服务器会创建一个唯一的Session ID,并将其发送给客户端。这个Session ID通常存储在客户端的cookie中。
  • 维护Session:每次用户请求时,客户端会将Session ID发送回服务器,服务器根据这个ID查找并维护用户的状态信息。
  • 销毁Session:当用户注销或Session超时时,服务器会销毁Session,释放资源

Session与Token的区别

在平常后端开发过程中,Token也是一种常用的登录验证方式。但总体而言,Token更适合现代Web应用

  • 存储位置:Session数据存储在服务器端,Token数据存储在客户端。
  • 安全性:Session相对安全,因为数据保存在服务器端,而Token安全性取决于Token的存储和传输方式,需要设置合理的期限
  • 状态管理:Session有状态,服务器需要维护每个用户的会话数据,而Token无状态,所有必要的信息都包含在Token中,服务器不维护会话数据。

基类介绍

LoginController继承自BaseController,BaseController的实现了基本的增删查改功能,并利用session记录用户登录信息

    @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        this.session = request.getSession(true);
        loginUser = (User) session.getAttribute("loginUser");
        session.setAttribute("kindList", illnessKindService.findList());
    }

该函数在每个子类函数执行之前调用,在http请求里面截获logingUser字段,根据这个字段来判断发出该请求的用户

1、注册接口register

注册接口的实现代码如下

 @PostMapping("/register")
    public RespResult register(User user, String code) {
        String email = user.getUserEmail();
        if (Assert.isEmpty(email)) {
            return RespResult.fail("邮箱不能为空");
        }
        Map<String, Object> codeData = (Map<String, Object>) session.getAttribute("EMAIL_CODE" + email);
        if (codeData == null) {
            return RespResult.fail("尚未发送验证码");
        }
        String sentCode = (String) codeData.get("code");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime((Date) codeData.get("time"));
        calendar.add(Calendar.MINUTE, 5);
        if (System.currentTimeMillis() > calendar.getTime().getTime()) {
            session.removeAttribute("EMAIL_CODE" + email);
            return RespResult.fail("验证码已经超时");
        }
        if (!sentCode.equals(code)) {
            return RespResult.fail("验证码错误");
        }
        List<User> query = userService.query(User.builder().userAccount(user.getUserAccount()).build());
        if (Assert.notEmpty(query)) {
            return RespResult.fail("账户已被注册");
        }
        user.setRoleStatus(0);
        user = userService.save(user);
        session.setAttribute("loginUser", user);
        return RespResult.success("注册成功", user);
    }

该注册接口提供了邮箱合法性判断、邮箱验证功能,并默认设置用户权限代码为0,也就是普通用户。邮箱验证的时限为5分钟,超过期限后会从session中移除验证码属性。

注册成功之后,保存user的id到session中

2、登录接口login

登录接口代码如下,总体思路和注册差不多,就是去验证仍然是登录成功后存储用户id到session,存目前加密功能仍在开发中,数据库中存储的密码为明文。

    @PostMapping("/login")
    public RespResult login(User user) {
        List<User> users = userService.query(user);
        if (Assert.notEmpty(users)) {
            session.setAttribute("loginUser", users.get(0));
            return RespResult.success("登录成功");
        }
        if (Assert.isEmpty(userService.query(User.builder().userAccount(user.getUserAccount()).build()))) {
            return RespResult.fail("账户尚未注册");
        }
        return RespResult.fail("密码错误");
    }

3、邮箱验证码发送接口sendEmailCode

访问该接口时,会给指定电子邮箱发送验证码

@PostMapping("/sendEmailCode")
    public RespResult sendEmailCode(String email, Map<String, Object> map) {
        if (StrUtil.isEmpty(email)) {
            return RespResult.fail("邮箱不可为空");
        }
        // 发送验证码
        String verifyCode = emailClient.sendEmailCode(email);
        map.put("email", email);
        map.put("code", verifyCode);
        map.put("time", new Date());
        session.setAttribute("EMAIL_CODE" + email, map);
        return RespResult.success("发送成功");
    }

4、登出

登出需要在session处注销


    @GetMapping("/logout")
    public String logout() {
        session.invalidate();
        return "redirect:/index.html";
    }

邮箱服务的整体实现我会在下一篇文章中说明

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值