山大软院创新项目实训(四)

目录

 

一、成果概述

二、方法1实现思路

1.发送邮件

yml配置文件:

后端发送邮件:

前端逻辑:

2.更新密码

后端接口逻辑:

前端调用后端API:

三、方法2实现思路

1.前端router

2.后端API

3.sql语句

4.前端Vue调用


 

一、成果概述

这段时间实现了2种改密码方式:

  • 邮箱改密码(原密码遗忘)
  • 用户更换密码(原密码已知)

其中邮箱改密码功能需要打开redis使用。

二、方法1实现思路

1.发送邮件

yml配置文件:

spring:
  mail:
    host: smtp.qq.com
    username: 280225*****@qq.com #邮箱
    password: ***********  #授权码
    protocol: smtp
    default-encoding: UTF-8
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
          ssl:
            enable: true

后端发送邮件:

@Value("${spring.mail.username}")//通过@Value注解读取 application-email 的username字段(也就是自己的邮箱)
    private String from;

    /**
     * 发送简单的邮箱
     *
     * @param to 收件人
     * @param theme 标题
     * @param content 正文内容
     * @param cc 抄送
     */
    public void sendSimpleMail(String to, String theme, String content, String... cc) {
        // 创建邮件对象
        SimpleMailMessage message = new SimpleMailMessage();

        try {
            message.setFrom(String.valueOf(new InternetAddress(from, "心灵导航系统", "UTF-8")));      // 发件人
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        message.setTo(to);          // 收件人
        message.setSubject(theme);  // 标题
        message.setText(content);   // 内容

        if (ArrayUtils.isNotEmpty(cc)) {
            message.setCc(cc);
        }

        // 发送
        javaMailSender.send(message);
    }

前端逻辑:

设计一个发送验证码按钮,倒计时60s,并在这期间将按钮设为禁用状态;

先获取请求权限,再获取邮箱验证码(具体逻辑已在后端实现),同时给出前端提示信息:

// 获取验证码
    sendEmailCode() {
      this.$refs.findPasswordForm.validateField('email', (valid) => {
        if(valid) {
          // 按钮倒计时
          this.disabled = true;
          this.msg = this.count-- + 's后重新获取';
          this.timer = setInterval(() => {
            this.msg = this.count-- + 's后重新获取';
            if (this.count < 0) {
              this.msg = '点击获取验证码';
              this.count = 60;
              this.disabled = false;
              clearInterval(this.timer);
            }
          }, 1000);
          // 发送验证码请求
          common.getRequestCode(this.findPasswordForm.email).then(_ => {
            common.getEmailCode(this.findPasswordForm.email, _.code).then(_ => {
              if(_) {
                // 通知邮箱发送
                this.$notify({
                  title: '邮箱验证码已发送',
                  message: '验证码有效时长5分钟, 失效请重新发送',
                  type: 'success',
                  duration: 10 * 1000
                })
              }else {
                this.$message({
                  type: "error",
                  message: "验证码发送失败,请重试"
                })
              }
            })
          })
        }
      });
    },

前端dialogue:

23aefbdb8261427abd983b26c3c2d75f.png

2.更新密码

后端接口逻辑:

接受前端传来的数据,进行初步检验(邮箱格式、密码限制等):

String email = userPasswordDTO.getEmail();
        String password = userPasswordDTO.getPassword();
        String code = userPasswordDTO.getCode();
        if (StringUtils.isAnyBlank(email, password, code)) {
            // 非空
            return Result.error(Constants.CODE_401,"参数为空");
        }else if (!StringUtil.checkEmail(email)) {
            // 邮箱格式校验
            return Result.error(Constants.CODE_600,"邮箱格式错误");
        }else if ( !StringUtil.checkPassword(password) ||code.length() != 6) {
            // 密码格式和验证码长度校验
            return Result.error(Constants.CODE_400,"参数错误");
        }
        return userService.findPassword(userPasswordDTO);//

然后根据获取的email查询数据库,看是否有这个用户;

若用户存在,则接着进行验证码的比对(需用到redis),如果一致则更新数据库存储的密码。

// 获取参数
        String email = userPasswordDTO.getEmail();
        String password = userPasswordDTO.getPassword();
        String code = userPasswordDTO.getCode();

        // 构造查询条件对象
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.select("id"); //查找id这一列
        wrapper.eq("email", email);//equal等于
        wrapper.last("limit 1");//无视优化规则直接拼到sql最后,有sql注入的风险

        // 查询用户,是否存在
        User user = this.baseMapper.selectOne(wrapper);// ???
        if (user == null) {
            return Result.error(Constants.CODE_600,"用户不存在");
        }

        // 获取正确的验证码
        String rightCode = redisTemplate.opsForValue().get(RedisConstant.EMAIL + email);
        if (!code.equals(rightCode)) {
            // 验证码比对
            return Result.error(Constants.CODE_400,"验证码不一致");
        }
        // 删除验证码
        redisTemplate.delete(RedisConstant.EMAIL + email);

        // 修改密码
        User user1 = new User();
        user1.setId(user.getId());
        user1.setPassword(SecureUtil.md5(password));

前端调用后端API:

// 请求
          user.findPassword(this.findPasswordForm).then(res => {
            if(res.code === '200') {
              // 请求成功
              this.$message({
                message: '密码修改成功',
                type: 'success'
              })

三、方法2实现思路

1.前端router

<el-dropdown-menu>
     <el-dropdown-item @click="stuortea">个人信息</el-dropdown-item>
     <el-dropdown-item @click="$router.push('/password')">修改密码</el-dropdown-item>
     <el-dropdown-item @click=quit>退出系统</el-dropdown-item>
</el-dropdown-menu>

 效果:

036778f1d1cf41efa9ea4573fb4fe905.png

鼠标悬停,出现下拉框,点击“修改密码”跳转到相关界面:

7fa440e6b5b743fcb2d5c014668566a2.png

对应代码:

<el-card style="width: 40%; margin: 10px">
      <el-form ref="form" :model="form" label-width="80px" :rules="rules">
        <el-form-item label="原密码" prop="password">
          <el-input v-model="form.password" show-password></el-input>
        </el-form-item>
        <el-form-item label="新密码" prop="newPassword">
          <el-input v-model="form.newPassword" show-password></el-input>
        </el-form-item>
        <el-form-item label="确认新密码" prop="confirmPass">
          <el-input v-model="form.confirmPass" show-password></el-input>
        </el-form-item>
      </el-form>

2.后端API

@ApiOperation("用户在设置里更新密码")
    @PostMapping("/updatePassword")
    public Result updatePassword(@RequestBody UserPasswordDTO userPasswordDTO) {
        String password = userPasswordDTO.getPassword();
        String newPassword = userPasswordDTO.getNewPassword();
        if (StrUtil.isBlank(password) ||StrUtil.isBlank(newPassword)) {
            return Result.error(Constants.CODE_400, "参数错误,部分参数为空");
        }
        if ( !StringUtil.checkPassword(newPassword) ) {
            // 密码格式校验
            return Result.error(Constants.CODE_400,"密码格式为:长度为6-18,只有数字和字母且至少包含1个字母");
        }
        userPasswordDTO.setPassword(SecureUtil.md5(password));
        userPasswordDTO.setNewPassword(SecureUtil.md5(newPassword));
        userService.updatePassword(userPasswordDTO);
        return Result.success();
    }

先判断前端传参是否有空值,然后再进行新密码格式的校验。

3.sql语句

@Update("update user set password = #{newPassword} where username = #{username} and password = #{password}")
    int updatePassword(UserPasswordDTO userPasswordDTO);

这里用username和md5加密后的密码查数据库,也就是说原密码正确时,即可修改为新密码。

4.前端Vue调用

changePass() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (this.form.newPassword !== this.form.confirmPass) {
            this.$message.error('2次输入新密码必须一致!')
            return
          }
          let user = JSON.parse(sessionStorage.getItem("user"))
          this.form.username = user.username
          request.post("/user/updatePassword", this.form).then(res => {
            if (res.code === '200') {
              this.$message({
                type: "success",
                message: "密码修改成功"
              })
              sessionStorage.removeItem("user")  //退出系统后清除缓存的user信息,不能通过路由访问数据了
              sessionStorage.removeItem("type")
              this.$router.push("/login")  //登录成功之后进行页面的跳转,跳转到主页

            } else {
              this.$message({
                type: "error",
                message: "修改失败"
              })
            }
          })
        }
      })
    }

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值