@TOC

1、父项目

1.1、依赖

2、前端项目

2.1、依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com</groupId><artifactId>0125-front</artifactId><version>1.0</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><!-- springboot核心 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- springboot web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
</project>

2.2、启动类

package com;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class FrontApplication {public static void main(String[] args) {SpringApplication.run(FrontApplication.class, args);}
}

2.3、yml文件

server:port: 8080

2.4、前端样式

放入webapp文件夹中

2.5、控制类

package com.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class ViewController {@RequestMapping("/")public String base(){System.out.println(">>> base");return "/demo.html";}
}

2.6、访问页面

然后启动启动类,就可以在网页访问到前端页面

3、配置集群

3.1/配置IP

3.2/集群配置


修改auto项目的application.yml文件的端口未8180

4/后端项目

4.1、依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>0125-email-sms-token</artifactId><groupId>com</groupId><version>1.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>auth</artifactId><dependencies><!-- springboot核心 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- springboot web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.2</version></dependency><!-- springboot mybaits整合 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!-- 数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.9</version></dependency><!-- java mail --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 辅助插件 --><dependency><groupId>cz.mallat.uasparser</groupId><artifactId>uasparser</artifactId><version>0.6.0</version></dependency><!-- token需要json依赖 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.31</version></dependency><!-- 容联云通讯 --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.6</version></dependency><dependency><groupId>com.cloopen</groupId><artifactId>CCPRestSDK</artifactId><version>2.7</version></dependency></dependencies>
</project>

4.2/邮箱验证码登录

4.2.1/邮箱发送验证码的流程

用户发送邮箱,服务器发送验证码给用户,并将用户和验证码存到redis上

代码

application.yml

server:port: 8101spring:datasource:type: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://localhost:3306/market?characterEncoding=utf-8username: rootpassword: 111111druid:driver-class-name: com.mysql.jdbc.Drivermail:host: smtp.163.com # 邮件服务器地址username: xxxx_test@163.com  # 发出邮件的邮箱password: DGBWOQAQEZYGWVQU # 发出邮箱的邮箱的验证码default-encoding: utf-8

password的授权码

sql代码,添加status关键字,默认值是1激活状态

实体类添加status关键字private Integer status;
添加util工具类
RedisUtil.java

package com.util;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;@Component
public class RedisUtil {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Resource(name = "stringRedisTemplate")private ValueOperations<String, String> valOpsStr;@Autowiredprivate RedisTemplate<Object, Object> redisTemplate;@Resource(name = "redisTemplate")private ValueOperations<Object, Object> valOpsObj;/*** 判断key是否存在* @param key* @return*/public boolean exists(String key){String value = getString(key);if (value == null) return false;return true;}/*** 获取失效时间* @param key* @return*/public long getExpire(String key){return redisTemplate.getExpire(key);}/*** 删除键* @param key*/public void delete(String key){redisTemplate.delete(key);}/*** 设置字符串数据* @param key* @param val*/public void setString(String key, String val){valOpsStr.set(key, val);}/*** 设置字符串数据* @param key 键* @param val 值* @param expire 有效时间*/public void setString(String key, String val, long expire){valOpsStr.set(key, val, expire, TimeUnit.SECONDS);}/*** 读取字符串数据* @param key* @return*/public String getString(String key){return valOpsStr.get(key);}
}

MD5.java

package com.util;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;public class MD5 {public static String getMd5(String plainText,int length) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(plainText.getBytes());byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0)i += 256;if (i < 16)buf.append("0");buf.append(Integer.toHexString(i));}// 32位// return buf.toString();// 16位// return buf.toString().substring(0, 16);return buf.toString().substring(0, length);} catch (NoSuchAlgorithmException e) {e.printStackTrace();return null;}}public static int getRandomCode(){       int max=9999;int min=1111;Random random = new Random();return random.nextInt(max)%(max-min+1) + min;       }public static void main(String[] args) {System.out.println(MD5.getMd5("helloadsfdsffsf",6));System.out.println(getRandomCode());}}

MailUtil.java

package com.util;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** 邮件发送接口的实现* @author hduser**/
@Component
public class MailUtil {@Autowiredprivate MailSender mailSender;/*** 发送邮件*/public void send(String mailTo, String mailFrom, String mailSubject, String mailText) {//邮件对象SimpleMailMessage mailMessage = new SimpleMailMessage();//设置发件人邮箱mailMessage.setFrom(mailFrom);//设置邮件主题mailMessage.setSubject(mailSubject);//设置收件人邮箱mailMessage.setTo(mailTo);//设置邮件内容mailMessage.setText(mailText);//发送邮件mailSender.send(mailMessage);}
}

重写UserService.java

package com.service;import com.bean.User;/*** 用户业务逻辑接口*/
public interface UserService extends BaseService<User> {/** 通过邮箱添加用户 */void addUserByMail(User user);/** 激活账号 */boolean active(String userName, String code);/** 通过手机号添加用户 */void addUserByPhone(User user);/** 发送激活码短信 */void sendActiveMessage(String userName);
}

UserServiceImpl.java

package com.service.impl;import com.bean.User;
import com.dao.UserMapper;
import com.service.UserService;
import com.util.MD5;
import com.util.MailUtil;
import com.util.RedisUtil;
import com.util.SmsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.Date;
import java.util.List;
import java.util.Map;/*** 用户业务逻辑实现*/
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper mapper;@Autowiredprivate MailUtil mailUtil;@Autowiredprivate RedisUtil redisUtil;@Autowiredprivate SmsUtil smsUtil;//激活码前缀private String active_prefix = "active:";//邮件激活码有效期private int timeForMail = 30;//手机激活码有效期private Integer timeForPhone = 2;@Transactional@Overridepublic int save(User user) {return mapper.insert(user);}@Overridepublic void addUserByMail(User user) {/* 验证账号邮箱是否可用 *//* 添加到数据库 *///设置账号状态user.setStatus(0);//添加mapper.insert(user);/* 发送邮件到用户邮箱 *///生成激活码String code = MD5.getMd5(new Date().toString(), 32);//发送激活码到用户邮箱mailUtil.send(user.getUserName(), "makey_test@163.com","激活【超市订单管理系统】账号","请在" + timeForMail + "分钟内激活账号, 激活码:" + code);//将激活码保存到redisredisUtil.setString(active_prefix + user.getUserName(),code, timeForMail * 60);}@Overridepublic boolean active(String userName, String code) {/* 判断, key是否存在 */if (!redisUtil.exists(active_prefix + userName)) return false;/* 比对激活码 *///获取redis中的激活码String value = redisUtil.getString(active_prefix + userName);//比对if (code.equals(value)) {//修改用户账号的状态mapper.update(new User(userName, 1));return true;}return false;}@Overridepublic void addUserByPhone(User user) {/* 验证账号邮箱是否可用 *//* 添加到数据库 *///设置账号状态user.setStatus(0);//添加mapper.insert(user);}@Overridepublic void sendActiveMessage(String userName) {/* 发送验证短信 *///生成手机激活码Integer code = MD5.getRandomCode();//发送到手机try {smsUtil.send(userName, "1",new String[]{code.toString(), timeForPhone.toString()});} catch (Exception e) {e.printStackTrace();}//将验证码保存到缓存redisUtil.setString(active_prefix + userName,code.toString(), timeForPhone.intValue()*60);}

controller.java

package com.controller;import com.bean.User;
import com.bean.dto.Dto;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class UserController {@Autowiredprivate UserService userService;@PostMapping("/registe/mail")@ResponseBodypublic Dto registeByEmail(User user){System.out.println(">>> 用户注册--邮箱");System.out.println(user);//添加用户userService.addUserByMail(user);return new Dto("注册成功, 请尽快激活账号!");}@PostMapping("/registe/phone")@ResponseBodypublic Dto registeByPhone(User user){System.out.println(">>> 用户注册--手机");System.out.println(user);//添加用户userService.addUserByPhone(user);return new Dto("注册成功, 请尽快激活账号!");}@PostMapping("/sms")@ResponseBodypublic Dto sendCode(String userName){System.out.println(">>> 获取手机激活码");System.out.println(userName);userService.sendActiveMessage(userName);return new Dto("激活码已发送!");}@PostMapping("/active")@ResponseBodypublic Dto active(String userName, String code){System.out.println(">>> 激活账号");System.out.println(userName + ", " + code);//激活boolean active = userService.active(userName, code);if (active)return new Dto("激活成功! 您可以登录网站了!");return new Dto("激活失败! 请重试!", "2000001");}
}

关于前端
由于前后端分咯,所以获取数据必须走post方面,所以前端要写Ajax

启动后

前缀要正确,否则会跳转不动


两个都要开启

4.2.2/手机注册和激活

和邮箱差不多,上述代码有写
区别:
https://www.yuntongxun.com/

SmsUtil.java

package com.util;import com.cloopen.rest.sdk.CCPRestSmsSDK;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Set;@Component
public class SmsUtil {/** 服务器地址 *///沙盒环境(用于应用开发调试): sandboxapp.cloopen.com//生产环境(用户应用上线使用): app.cloopen.comprivate String smsServerIP = "sandboxapp.cloopen.com";/** 服务器端口 */private String port = "8883";/** acount sid 主账号 */private String smsAccountSid = "8aaf0708762cb1cf017731fa1e525b15";/** auth token 主账号令牌 */private String smsAuthToken = "a3852ead06be4d95a052e344f2d67409";/** 应用ID */private String smsAppID = "8aaf0708762cb1cf017731fa1f205b1c";public void send(String to, String templateId, String[] datas) throws Exception {//短信发送结果HashMap<String, Object> result = null;//初始化SDK,这是云通讯给出的jar包,需要手动导入CCPRestSmsSDK restAPI = new CCPRestSmsSDK();//******************************注释*********************************************//*初始化服务器地址和端口                                                       *//*沙盒环境(用于应用开发调试):restAPI.init("sandboxapp.cloopen.com", "8883");*//*生产环境(用户应用上线使用):restAPI.init("app.cloopen.com", "8883");       *//*******************************************************************************restAPI.init(smsServerIP, port);//******************************注释*********************************************//*初始化主帐号和主帐号令牌,对应官网开发者主账号下的ACCOUNT SID和AUTH TOKEN     *//*ACOUNT SID和AUTH TOKEN在登陆官网后,在“应用-管理控制台”中查看开发者主账号获取*//*参数顺序:第一个参数是ACOUNT SID,第二个参数是AUTH TOKEN。                   *//*******************************************************************************restAPI.setAccount(smsAccountSid,smsAuthToken);//******************************注释*********************************************//*初始化应用ID                                                                 *//*测试开发可使用“测试Demo”的APP ID,正式上线需要使用自己创建的应用的App ID     *//*应用ID的获取:登陆官网,在“应用-应用列表”,点击应用名称,看应用详情获取APP ID*//*******************************************************************************
//      restAPI.setAppId(systemConfig.getSmsAppID());restAPI.setAppId(smsAppID);//******************************注释****************************************************************//*调用发送模板短信的接口发送短信                                                                  *//*参数顺序说明:                                                                                  *//*第一个参数:是要发送的手机号码,可以用逗号分隔,一次最多支持100个手机号                          *//*第二个参数:是模板ID,在平台上创建的短信模板的ID值;测试的时候可以使用系统的默认模板,id为1。    *//*系统默认模板的内容为“【云通讯】您使用的是云通讯短信模板,您的验证码是{1},请于{2}分钟内正确输入”*,测试只能1//*第三个参数是要替换的内容数组。                                                                                                                              *//**************************************************************************************************//**************************************举例说明***********************************************************************//*假设您用测试Demo的APP ID,则需使用默认模板ID 1,发送手机号是13800000000,传入参数为6532和5,则调用方式为           *//*result = restAPI.sendTemplateSMS("13800000000","1" ,new String[]{"6532","5"});                                                                       *//*则13800000000手机号收到的短信内容是:【云通讯】您使用的是云通讯短信模板,您的验证码是6532,请于5分钟内正确输入     *//*********************************************************************************************************************result = restAPI.sendTemplateSMS(to,templateId,datas);System.out.println("SDKTestGetSubAccounts result=" + result);if("000000".equals(result.get("statusCode"))){//正常返回输出data包体信息(map)HashMap<String,Object> data = (HashMap<String, Object>) result.get("data");Set<String> keySet = data.keySet();for(String key:keySet){Object object = data.get(key);System.out.println(key +" = "+object);}}else{//异常返回输出错误码和错误信息System.out.println("错误码=" + result.get("statusCode") +" 错误信息= "+result.get("statusMsg"));throw new Exception("错误码=" + result.get("statusCode") +" 错误信息= "+result.get("statusMsg"));}}
}



管理测试号码

可以去缓存里看验证码
操作
UserService.java

   /** 通过手机号添加用户 */void addUserByPhone(User user);/** 发送激活码短信 */void sendActiveMessage(String userName);

UserServiceImpl.java

  //激活码前缀private String active_prefix = "active:";//邮件激活码有效期private int timeForMail = 30;//手机激活码有效期private Integer timeForPhone = 2;@Overridepublic boolean active(String userName, String code) {/* 判断, key是否存在 */if (!redisUtil.exists(active_prefix + userName)) return false;/* 比对激活码 *///获取redis中的激活码String value = redisUtil.getString(active_prefix + userName);//比对if (code.equals(value)) {//修改用户账号的状态mapper.update(new User(userName, 1));return true;}return false;}@Overridepublic void addUserByPhone(User user) {/* 验证账号邮箱是否可用 *//* 添加到数据库 *///设置账号状态user.setStatus(0);//添加mapper.insert(user);}@Overridepublic void sendActiveMessage(String userName) {/* 发送验证短信 *///生成手机激活码Integer code = MD5.getRandomCode();//发送到手机,模板只能选1try {smsUtil.send(userName, "1",new String[]{code.toString(), timeForPhone.toString()});} catch (Exception e) {e.printStackTrace();}//将验证码保存到缓存redisUtil.setString(active_prefix + userName,code.toString(), timeForPhone.intValue()*60);}

controller.java

@PostMapping("/sms")@ResponseBodypublic Dto sendCode(String userName){System.out.println(">>> 获取手机激活码");System.out.println(userName);userService.sendActiveMessage(userName);return new Dto("激活码已发送!");}@PostMapping("/active")@ResponseBodypublic Dto active(String userName, String code){System.out.println(">>> 激活账号");System.out.println(userName + ", " + code);//激活boolean active = userService.active(userName, code);if (active)return new Dto("激活成功! 您可以登录网站了!");return new Dto("激活失败! 请重试!", "2000001");}

springboot前后端分离,邮箱/手机验证号激活和登录,手机注册和激活相关推荐

  1. 前后端分离之权限验证

    前后端分离之权限验证 原理:将登录验证的请求头中后端生成的秘钥(token)接收后存储在cookie内,在再次请求数据时添加在请求头中发送给后端验证,请求数据. 代码: 登录ajax: $scope. ...

  2. Android+SpringBoot前后端分离实现登录注册

    Android+SpringBoot前后端分离实现登录注册 一.登录 1.界面设计 2.Android端 (1)布局文件(activity_login) (2)java文件(LoginActivity ...

  3. springboot前后端分离后权限原理浅谈

    1. 需求描述 最近在梳理springboot前后端分离后的权限管理问题.前段时间,已经把shiro的实现和spring security 的实现进行了初步的了解.如果深入细节,一个篇幅怕是不够.本文 ...

  4. B站云E办Vue+SpringBoot前后端分离项目——MVC三层架构搭建后台项目

    本项目来源B站云E办,笔记整理了项目搭建的过程和涉及的知识点.对于学习来说,不是复制粘贴代码即可,要知其然知其所以然.希望我的笔记能为大家提供思路,也欢迎各位伙伴的指正. 项目前端学习笔记目录 B站云 ...

  5. 前后端分离的用户验证原理及Spring Boot + JWT的框架搭建(附完整的框架代码)之二

    本篇承接上一篇,关于Session以及JWT Token参考: 前后端分离的用户验证原理及Spring Boot + JWT的框架搭建(附完整的框架代码)之一 框架整体描述 框架使用Spring Bo ...

  6. SpringBoot后台管理+Uniapp(混合APP)前端 之 酒店住宿+景点下单管理系统(SpringBoot前后端分离)

    酒店住宿+景点下单管理系统(SpringBoot前后端分离) 之 SpringBoot后台管理+Uniapp(混合APP)前端 SpringBoot前后端分离项目-Thymeleaf模板引擎景区旅游管 ...

  7. 基于SpringBoot前后端分离的众筹系统(附源码)

    基于SpringBoot前后端分离的众筹系统源码下载链接: https://download.csdn.net/download/weixin_47367099/85441573 一.运行步骤 1.环 ...

  8. 新手摸爬滚打:vue+springboot前后端分离项目演示(三)——axios实现前后端交互

    导语:路漫漫其修远兮,吾将上下而求索 前篇: 新手摸爬滚打:vue+springboot前后端分离项目演示(一)--vue cli创建vue2项目 新手摸爬滚打:vue+springboot前后端分离 ...

  9. SpringBoot前后端分离项目中如何制作前端jar包(类似swaggerUI前端jar包制作方法)

    SpringBoot前后端分离项目中如何制作前端jar包(类似swaggerUI前端jar包制作方法) 可用于SpringBoot引用的前端UI的Jar包,类似于SwaggerUI包 WABJAR介绍 ...

  10. SSM+JWT实现前后端分离的token验证

    SSM+JWT实现前后端分离的token验证 前言 什么是JWT 基于Token的验证流程 JWT的Token实现 后端部分 前端部分 测试 项目完整地址 前言 以前写的web项目都是没有前后端分离的 ...

最新文章

  1. live555实现视频格式数据流化处理
  2. css中哪些属性与创建多列相关,css3中的新增属性有哪些
  3. node --- koa、Mongoose、vue联系知识梳理
  4. 进程的退出方式以及僵尸进程和孤儿进程
  5. [AGC009B] Tournament(多叉树转二叉树后的最小可能深度)
  6. 使用Servlet 3.0,Redis / Jedis和CDI的简单CRUD –第1部分
  7. Feign Hystrix (HystrixCommonKey) 设置单独接口的超时时间和FallBack
  8. 【Java】关键词strictfp解析
  9. 年末阿里百度等大厂技术面试题汇总,不可思议!
  10. 畅玩4x 刷linux,荣耀4x如何root
  11. 自然语言处理——BERT情感分类实战(一)之预处理
  12. 嵌入式语音识别系统之电路设计原理
  13. envi反演水质参数_基于大气校正法的Landsat 8 TIRS地表温度反演
  14. 【排列组合、思维】Combinatorics Homework
  15. 用visio制作机柜服务器,visio 绘制机柜接线图 实例教程
  16. 破解网址_中国目前的破解组织大全
  17. android平板电脑的虚拟键盘,苹果平板电脑ipad虚拟键盘介绍 ipad虚拟键盘使用方法【详解】...
  18. 李飞飞计算机视觉笔记(1)--数据驱动的图像分类方式:K最近邻与线性分类器
  19. 香港理工大学李青教授团队招收机器学习方向全奖博士/博后/RA
  20. Android 动画方案

热门文章

  1. 自学编程系列——4 Numpy数组
  2. Android webview登录手机QQ
  3. 智能车入门——元素识别与循迹
  4. 3D建模和渲染吃CPU还是显卡?专业显卡和游戏显卡的区别
  5. 树莓派实现温控风扇智能降温
  6. html时间轴横向自动播放,利用jQuery实现日期时间轴自动播放代码
  7. 超越杯编程大赛前线报道
  8. [百家号]大英帝国的人口和面积比现在的英国大多少?
  9. C++ MFC学习笔记(第三课)绘制统计直方图
  10. 微星 MPG B460I GAMING EDGE WIFI +i5-10400电脑 Hackintosh 黑苹果efi引导文件