Java注册登录及邮箱发送账号激活(主要技术栈SpringBoot,MyBatis)(下篇)

举报
秋名山码民 发表于 2023/01/11 22:16:37 2023/01/11
【摘要】 后端代码 格式典型的分层模型, pojopackage com.expamle.emailloginregister.pojo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;import java.time.Loc...

后端代码

格式

在这里插入图片描述

典型的分层模型,

pojo

package com.expamle.emailloginregister.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {

        private Integer id; // 主键Id

        private String email; // 邮箱

        private String password; // 密码 md5+盐

       /* @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")*/
        private LocalDateTime activationTime; // 激活失效时间

        private String confirmCode; // 确认代码

        private Integer isVaild; // 是否可用 0-不可用 1-可用

        private String salt; // 加密盐

/*
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
*/
        private LocalDateTime gmtCreate; // 创建时间

/*
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
*/
        private LocalDateTime gmtModified; // 修改时间
}

mapper

主要通过mybatis来写一些与user相关的sql语句

package com.expamle.emailloginregister.mapper;

import com.expamle.emailloginregister.pojo.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserMapper {

    /**
     * 注册插入用户信息
     * */
    @Insert("insert into user(email,password,activation_time,confirm_code,is_vaild,salt,gmt_create,gmt_modified)" +
            "values(#{email},#{password},#{activationTime},#{confirmCode},#{isVaild},#{salt},#{gmtCreate},#{gmtModified})")
    int insertUser(User user);

    /**
     * 根据confirm_code查询与用户是否已激活
     * confirm_code
     * is_vaild
     * */
    @Select("select email,activation_time from user where confirm_code = #{confirmCode} and is_vaild = 0")
    User findUserByConfirmCode(@Param("confirmCode") String confirmCode);

    /**
     * 根据激活码查询用户 并 修改状态值
     * */
    @Update("update user set is_vaild=1 where confirm_code = #{confirmCode}")
    int confirmUser(@Param("confirmCode") String confirmCode);

    /**
     * 根据邮箱查询账号
     * */
    @Select("select email,password,salt from user where email=#{email} and is_vaild=1")
    List<User> findUserByEmail(@Param("email") String email);

    /**
     * 用户查重
     * */
    @Select("select count(*) from user where email=#{email} limit 1")
    int emailExist(@Param("email") String email);
}

Controller

与前端页面进行交互,负责一个登录,注册数据的提交和响应

SystemController

package com.expamle.emailloginregister.controller;

import com.expamle.emailloginregister.pojo.User;
import com.expamle.emailloginregister.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
*@Controller 不可使用RestControoler
*使用RestController要进行一个封装
*/
@Controller
public class SystemController {
    @Autowired
    private UserService userService;

    /**
     * 登录
     * */
    @GetMapping("/login")
    public String login(){

       return "login";
    }

    /**
     * 注册
     * */
    @GetMapping("/registry")
    public String registry(User user){
        return "registry";
    }
}

UserController

package com.expamle.emailloginregister.controller;

import com.expamle.emailloginregister.pojo.User;
import com.expamle.emailloginregister.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("users")
public class UserController {
@Autowired
    private UserService userService;

    /**
     * 注册账号
     * */
    @PostMapping("register")
    public Map<String,Object> registery(User user){

      Map<String,Object> map  =  userService.createAccount(user);

        return map;
    }

    /**
     * 用户登录
     * */
    @PostMapping("login")
    public Map<String,Object> login(User user){

        Map<String,Object> map = userService.accountLogin(user);

        return map;
    }

    /**
     * 账号激活
     * 激活码附在请求后
     *
     * */
    @GetMapping("activation")
    public Map<String,Object> activationAccount(String confirmCode){
        Map<String,Object> map = userService.activationAccount(confirmCode);

        return map;
    }
}

service

在这里插入图片描述
先写俩个接口,在Impl中进行实现,
EmailServiceImpl

package com.expamle.emailloginregister.service;

public interface EmailService {

    void sendEmail(String email,String activationUrl);

}

实现sendEmail

package com.expamle.emailloginregister.service.Impl;

import com.expamle.emailloginregister.service.EmailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;

/**
 * 发送邮件相关业务
 * */
@Service
public class EmailServiceImpl implements EmailService {

    // 引入配置文件属性
    @Value("${spring.mail.username}")
    private String sendUsername;


    // javamain mail依赖方法---此方法无法使用autowird注入,javaMailSender不是springboot的方法
    @Resource
    private JavaMailSender javaMailSender;

    @Resource //同上
    private TemplateEngine templateEngine;

    public void sendEmail(String email,String activationUrl){

        // 创建邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();

        try {

            /**
             * MineMessagehelper---设置邮件相关内容
             * @Params1 邮件对象
             * @Params2 是否发送多封邮件
             * */
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage,true);

            // 设置邮件主题
            message.setSubject("注册账号激活");

            // 设置邮件发送者
            message.setFrom(sendUsername);

            // 设置邮件接收者,可多个
            message.setTo(email);

            // 设置邮件抄送人
           /* message.setCc();*/

            // 设置邮件隐秘抄送人,可多个
            /*message.setBcc();*/

            // 设置邮件发送日期
            message.setSentDate(new Date());

            // 创建上下文环境--thym依赖提供方法,使用当前本地前端
            Context context = new Context();
            // 邮件中传递的链接
            context.setVariable("activationUrl",activationUrl);


            // 映射html文件
            String text = templateEngine.process("activation-account.html",context);

            // 设置邮件正文-true-是否是html模板
            message.setText(text,true);

                   } catch (MessagingException e) {
            e.printStackTrace();
        }

        // 发送邮件
        javaMailSender.send(mimeMessage);
    }
}

UserService

package com.expamle.emailloginregister.service;

import com.expamle.emailloginregister.pojo.User;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

@Transactional
public interface UserService {

    Map<String,Object> createAccount(User user);

    Map<String, Object> accountLogin(User user);

    Map<String, Object> activationAccount(String confirmCode);
}

具体实现

package com.expamle.emailloginregister.service.Impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.expamle.emailloginregister.mapper.UserMapper;
import com.expamle.emailloginregister.pojo.User;
import com.expamle.emailloginregister.service.EmailService;
import com.expamle.emailloginregister.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
   @Autowired
   private UserMapper userMapper;

   @Autowired
   private EmailService emailService;

   /**
    * 用户注册
    * */
    @Override
    public Map<String,Object> createAccount(User user) {

        // 统一返回对象
        Map<String,Object> result = new HashMap<>();

        /**
         * 注册--构建User对象内的数据
         *  前端返回参数 email、password
         * */

        // 判断邮箱是否已经存在
        int emailExist = userMapper.emailExist(user.getEmail());
        if (emailExist == 1){
            result.put("code",400);
            result.put("msg","用户已存在");
            return result;
        }

        //开始构建user数据

        // 激活码--hutool工具生成雪花算法
        String confirmCode = IdUtil.getSnowflake(1,1).nextIdStr();
        user.setConfirmCode(confirmCode);

        // 加密密码  password+盐+md5
        String password = user.getPassword();
        String salt = RandomUtil.randomString(6); // hutool随机生成6个字符
        String md5Pwd = SecureUtil.md5(password+salt);

        // 设置user参数、salt、password
        user.setSalt(salt);
        user.setPassword(md5Pwd);

        // 是否已激活 默认-0 未激活
        user.setIsVaild(0);

        // 激活码有效期
        LocalDateTime activationTime = LocalDateTime.now().plusDays(1); // 当前时间增加1天时间
        user.setActivationTime(activationTime);

        // 创建时间
        LocalDateTime nowTime = LocalDateTime.now();
        user.setGmtCreate(nowTime);
        user.setGmtModified(nowTime);

        // 用户信息插入数据库
        int insertUser = userMapper.insertUser(user);

        // 判断数据库写入是否成功并返回相关信息
        if (insertUser > 0){

            // 准备激活链接
            String activationUrl ="http://localhost:8001/users/activation?confirmCode="+confirmCode;

            //发送邮箱信息
             emailService.sendEmail(user.getEmail(), activationUrl);

            result.put("code",200);
            result.put("msg","注册成功,请前往邮箱激活账号");
            return result;
        }else{
            result.put("code",400);
            result.put("msg","注册失败");
            return result;
        }
    }

    public static void main(String[] args) {
        String a = SecureUtil.md5("123456"+"qldp40");
        System.out.println(a);
    }

    /**
     * 用户登录
     * */
    @Override
    public Map<String, Object> accountLogin(User user) {
        // 统一返回数据
        Map<String,Object> result = new HashMap<>();


        // 前端数据校验
       if (user.getEmail() == null || user.getEmail().isEmpty() ||
            user.getPassword() == null || user.getPassword().isEmpty()
           ){
                result.put("code",400);
                result.put("msg","请输入账号和密码");
                return result;
       }


       // 查询用户是否在数据库中
        List<User> users = userMapper.findUserByEmail(user.getEmail());

        // 判断用户是否异常
        if (users == null || users.isEmpty()){
            result.put("code",400);
            result.put("msg","账号未注册或未激活");
            return result;
        }

        // 查询出多个账号
        if (users.size()>1){
            result.put("code",400);
            result.put("msg","账号异常请联系管理员");
            return result;
        }

        // 得到唯一用户-判断账号是否激活
        User DbUser = users.get(0);

        // 校验密码-获取加密数据
        String salt = DbUser.getSalt();
        String md5Pwd = SecureUtil.md5(user.getPassword()+salt);

        /**
         * DbUser.getPassword().equals(md5Pwd)---可以匹配
         * md5Pwd.equals(DbUser.getPassword())---无法匹配 ??????
         * */
        if (DbUser.getPassword().equals(md5Pwd)){
            result.put("code",200);
            result.put("msg","登录成功");
            return result;
        }else {
            result.put("code",400);
            result.put("msg","账号或密码有误");
            return result;
        }

    }

    /**
     * 激活账号
     * */
    @Override
    public Map<String, Object> activationAccount(String confirmCode) {
        // 统一返回参数
        Map<String, Object> map = new HashMap<>();

        // 通过confirmCount查询用户
        User user = userMapper.findUserByConfirmCode(confirmCode);

        System.out.println(user.toString());

        if (user == null ){
            map.put("code",400);
            map.put("msg","账号未注册");
            return map;
        }

        // 判断激活码有效期
        // 当前时间是否在激活码截止期之后
        boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
        if (after){
            map.put("code",400);
            map.put("msg","链接已失效,请重新获取激活码");
            return map;
        }

        // 激活账号,修改状态为 1
        int confirmUser = userMapper.confirmUser(confirmCode);
        if (confirmUser == 1){
            map.put("code",200);
            map.put("msg","激活账号成功");
            return map;
        }else{
            map.put("code",400);
            map.put("msg","激活账号失败");
            return map;
        }

    }
}

最后

码云完整代码及部署教程:
https://gitee.com/Vamye/LoginDemo

参考b站视频:马士兵教程

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。