فهرست منبع

[charge-admin][功能增加]:增加发送邮件,重置密码

yxp 1 سال پیش
والد
کامیت
62d7f36d1f

+ 8 - 0
ruoyi-admin/src/main/resources/application-dev.yml

@@ -138,6 +138,14 @@ spring:
         wall:
           config:
             multi-statement-allow: true
+  #重置邮箱配置
+  mail:
+    #重置地址前缀
+    url: http://127.0.0.1:8090
+    default-encoding: UTF-8
+    username: postmaster@weguyun.com
+    password: weguyun#2024
+    host: smtp.mxhichina.com
 # token配置
 token:
     # 令牌自定义标识

+ 8 - 0
ruoyi-admin/src/main/resources/application-guowai.yml

@@ -137,6 +137,14 @@ spring:
         wall:
           config:
             multi-statement-allow: true
+  #重置邮箱配置
+  mail:
+    #重置地址前缀
+    url: https://ev.weguyun.com
+    default-encoding: UTF-8
+    username: postmaster@weguyun.com
+    password: weguyun#2024
+    host: smtp.mxhichina.com
 # token配置
 token:
   # 令牌自定义标识

+ 7 - 0
ruoyi-common/pom.xml

@@ -148,6 +148,13 @@
             <artifactId>knife4j-spring-boot-starter</artifactId>
             <version>2.0.9</version>
         </dependency>
+        <!-- https://mvnrepository.com/artifact/javax.mail/mail -->
+        <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+            <version>1.4.7</version>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 110 - 0
ruoyi-common/src/main/java/com/ruoyi/common/MailUtils.java

@@ -0,0 +1,110 @@
+package com.ruoyi.common;
+
+import java.util.Properties;
+
+import javax.mail.Authenticator;
+
+import javax.mail.Message;
+
+import javax.mail.Message.RecipientType;
+
+import javax.mail.MessagingException;
+
+import javax.mail.PasswordAuthentication;
+
+import javax.mail.Session;
+
+import javax.mail.Transport;
+
+import javax.mail.internet.*;
+
+
+import com.sun.mail.util.MailSSLSocketFactory;
+
+/**
+ * @author xp
+ * @date 2024/5/9
+ * @explain "  "
+ */
+public class MailUtils {
+    public static void sendMail(String host, String username, String password, String sendToMail, String subject, String restUrl) throws Exception {
+
+        //1.创建连接对象,连接到邮箱服务器
+
+        Properties props = System.getProperties();
+
+        //Properties 用来设置服务器地址,主机名 。。 可以省略
+
+        //设置邮件服务器
+
+        props.setProperty("mail.smtp.host", host);
+
+        props.put("mail.smtp.auth", "true");
+
+        //SSL加密
+
+        MailSSLSocketFactory sf = new MailSSLSocketFactory();
+
+        sf.setTrustAllHosts(true);
+
+        props.put("mail.smtp.ssl.enable", "true");
+
+        props.put("mail.smtp.ssl.socketFactory", sf);
+
+        //props:用来设置服务器地址,主机名;Authenticator:认证信息
+
+        Session session = Session.getDefaultInstance(props, new Authenticator() {
+
+            @Override
+
+            //通过密码认证信息
+
+            protected PasswordAuthentication getPasswordAuthentication() {
+
+                //new PasswordAuthentication(用户名, password);
+
+                //这个用户名密码就可以登录到邮箱服务器了,用它给别人发送邮件
+
+                return new PasswordAuthentication(username, password);
+            }
+        });
+        try {
+
+            Message message = new MimeMessage(session);
+
+            //2.1设置发件人:
+
+            message.setFrom(new InternetAddress(username));
+
+            //2.2设置收件人 这个TO就是收件人
+
+            message.setRecipient(RecipientType.TO, new InternetAddress(sendToMail));
+
+            //2.3邮件的主题
+
+            message.setSubject(subject);
+
+            //2.4设置邮件的正文 第一个参数是邮件的正文内容 第二个参数是:是文本还是html的连接
+
+            MimeBodyPart mimeBodyPart = new MimeBodyPart();
+            mimeBodyPart.setContent("<span style='font-size:20px'>You are resetting your password, please take action within 1 minute; Reset password address:<a href='"+restUrl+"'>RESET PASSWORD</a></span>","text/html");
+            MimeMultipart mimeMultipart = new MimeMultipart();
+            mimeMultipart.addBodyPart(mimeBodyPart);
+
+            message.setContent(mimeMultipart);
+
+            //3.发送一封激活邮件
+
+            Transport.send(message);
+
+        } catch (MessagingException mex) {
+
+            mex.printStackTrace();
+
+        }
+
+    }
+
+
+
+}

+ 5 - 0
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java

@@ -139,4 +139,9 @@ public class Constants
      */
     public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
             "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
+
+    /**
+     * 用户重置密码,加密密钥
+     */
+    public static final String RESET_PWD_KEY ="WaGGaDaE81aAaYQX";
 }

+ 43 - 5
ruoyi-thirduser/src/main/java/com/ruoyi/thirduser/controller/LoginController.java

@@ -1,20 +1,25 @@
 package com.ruoyi.thirduser.controller;
 
+import com.ruoyi.common.MailUtils;
 import com.ruoyi.common.annotation.Anonymous;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.model.LoginBody;
 import com.ruoyi.common.core.domain.model.RegisterBody;
+import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.thirduser.service.SendMailService;
 import com.ruoyi.thirduser.service.ThirdUserloginService;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.PostConstruct;
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
 import javax.servlet.http.HttpServletRequest;
+import java.util.Base64;
+import java.util.concurrent.TimeUnit;
 
 @Slf4j
 @RestController
@@ -23,6 +28,12 @@ public class LoginController {
     @Autowired
     private ThirdUserloginService thirdUserloginService;
 
+    @Autowired
+    private SendMailService sendMailService;
+
+    @Autowired
+    private RedisCache redisCache;
+
     @PostMapping("/mailLogin")
     @Anonymous
     public AjaxResult mailLogin(@RequestBody LoginBody loginBody){
@@ -49,10 +60,37 @@ public class LoginController {
 
     @PostMapping("/forgetPwd")
     @Anonymous
-    public AjaxResult forgetPwd(HttpServletRequest request){
+    public AjaxResult forgetPwd(HttpServletRequest request) {
         String account = request.getParameter("username");
+        if (redisCache.hasKey(Constants.RESET_PWD_KEY+account)){
+            long expire = redisCache.getExpire(Constants.RESET_PWD_KEY + account);
+            return AjaxResult.error("Try again in "+expire+" seconds");
+        }
+        sendMailService.sendMailCode(account);
         String lng = request.getParameter("locale");
         return AjaxResult.success(true);
+    }
 
+    @GetMapping("/restPwd/{token}")
+    @Anonymous
+    public AjaxResult restPwd(@PathVariable String token) {
+        try {
+            // 使用AES算法创建Cipher对象
+            Cipher cipher = Cipher.getInstance("AES");
+            // 创建密钥对象
+            SecretKeySpec secretKeySpec = new SecretKeySpec(Constants.RESET_PWD_KEY.getBytes(), "AES");
+            // 初始化Cipher对象为解密模式
+            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
+            // 解密数据
+            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(token));
+            String username = new String(decryptedBytes);
+            //System.out.println("解密后的邮箱: " + username);
+            if (!redisCache.hasKey(Constants.RESET_PWD_KEY+username)){
+                return AjaxResult.error("The connection is invalid!");
+            }
+            return thirdUserloginService.updateUserPwd(username);
+        } catch (Exception e) {
+            return AjaxResult.error();
+        }
     }
 }

+ 79 - 0
ruoyi-thirduser/src/main/java/com/ruoyi/thirduser/service/SendMailService.java

@@ -0,0 +1,79 @@
+package com.ruoyi.thirduser.service;
+
+import com.ruoyi.common.MailUtils;
+import com.ruoyi.common.constant.CacheConstants;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.redis.RedisCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author xp
+ * @date 2024/5/9
+ * @explain "  "
+ */
+@Service
+public class SendMailService {
+
+    @Value("${spring.mail.host:null}")
+    private String host;
+
+    @Value("${spring.mail.username:null}")
+    private String username;
+
+    @Value("${spring.mail.password:null}")
+    private String password;
+
+    @Value("${spring.mail.subject:RESET PASSWORD}")
+    private String subject;
+
+    @Value("${spring.mail.url:null}")
+    private String url;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    private static final Logger log = LoggerFactory.getLogger(SendMailService.class);
+
+    public AjaxResult sendMailCode(String sendToMail) {
+
+        try {
+            // 使用AES算法创建Cipher对象
+            Cipher cipher = Cipher.getInstance("AES");
+            // 创建用于加密的密钥对象;直接使用
+            SecretKeySpec secretKeySpec = new SecretKeySpec(Constants.RESET_PWD_KEY.getBytes(), "AES");
+            // 初始化Cipher对象为加密模式
+            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
+            // 加密数据
+            byte[] encryptedBytes = cipher.doFinal(sendToMail.getBytes());
+
+            String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
+            //重置连接
+            String restUrl = url + "/restPwd/" + encryptedText;
+
+            redisCache.setCacheObject(Constants.RESET_PWD_KEY+sendToMail,sendToMail,1,TimeUnit.MINUTES);
+
+            //发送邮件
+            MailUtils.sendMail(host, username, password, sendToMail, subject, restUrl);
+        } catch (Exception e) {
+            log.debug("Failed to send reset the link.");
+            e.printStackTrace();
+            return null;
+        }
+        return AjaxResult.success(true);
+    }
+
+}

+ 10 - 0
ruoyi-thirduser/src/main/java/com/ruoyi/thirduser/service/ThirdUserloginService.java

@@ -2,6 +2,7 @@ package com.ruoyi.thirduser.service;
 
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
+import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.redis.RedisCache;
@@ -150,4 +151,13 @@ public class ThirdUserloginService  {
     public int deleteUser(Long userId) {
        return userService.deleteUserById(userId);
     }
+    public AjaxResult updateUserPwd(String username) {
+        SysUser sysUser = userService.selectUserByUserName(username);
+        if (sysUser==null){
+            return AjaxResult.error("The user does not exist!");
+        }
+        sysUser.setPassword(SecurityUtils.encryptPassword("123456"));
+        userService.updateUser(sysUser);
+        return AjaxResult.success("The original password was reset successfully,Please go back to login!");
+    }
 }