B070-项目实战-用户模块--手机注册

这篇具有很好参考价值的文章主要介绍了B070-项目实战-用户模块--手机注册。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

用户模块需求分析

用户注册
  登录信息
  基本信息
  安全信息
用户登录
  账号登录
  扫码登录-自己app扫描页面
  三方登录-使用三方app(微信,qq,支付宝等)
  验证码登录-自己做  reids.set(logincode+phone,xxx)
用户管理
地址管理
收藏
   商品收藏
   店铺收藏
   服务收藏
   宠物收藏
   。。。。
足迹
   。。。。

静态网站部署与调试

两种前端项目的部署

vue-cli项目:pethome-admin(管理员的管理界面),用npm打包成静态项目后丢进Tomcat服务器跑
Css+div项目:pethome_web(用户访问门户网站),本身是静态项目可以直接丢进Tomcat服务器跑

两种前端项目的调试(热部署)

vue-cli项目可以npm run dev启动调试
传统静态项目需要安装 live-server服务器来调试,这个服务器很简单就是node的一个模块,
全局安装:npm install -g live-server,运行:live-server --port=80

创建静态web项目

拷贝amz_02_adp的two里项目资源到pethome-web目录下
复制home3.html到pethome-web根目录并改名为index.html作为首页
修改css和js引用路径

进入web子项目
全局安装:npm install -g live-server
启动调试:live-server --port=80

替换images图片

注册分析与设计

分析需求
注册分为:邮箱注册,和手机号注册,逻辑都是一样的,只是激活方式不一样。

  手机号注册:
    1)输入手机号
    2)获取验证码并且输入
    3)输入蜜马和确认蜜马
    4)完成注册
设计 界面设计(ui)设计表(后台) 流程设计(后台)
三范式

1NF:列的原子性,不可再拆分
2NF:行唯一,
3NF:如果一张表的数据能够通过其他表推导出来,不应该单独设计,应该通过外键的方式关联查询出来。

反3NF:有的时候我们为了增强查询效率,会设计一些冗余字段,变多表查询为单表查询。

表设计

B070-项目实战-用户模块--手机注册,笔记总结,java,es6,前端
B070-项目实战-用户模块--手机注册,笔记总结,java,es6,前端
注意:以后只要在eployee或user操作时涉及到登录信息都要同步操作logininfo。比如添加员工也要在logininfo添加一条记录,注册用户也要在logininfo中添加。同理删除或修改也要同步。

流程设计

见文档

相关技术准备
1.随机字符串(用StrUtils工具类)
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author yaohuaipeng
 * @date 2018/10/26-16:16
 */
public class StrUtils {
    /**
     * 把逗号分隔的字符串转换字符串数组
     *
     * @param str
     * @return
     */
    public static String[] splitStr2StrArr(String str,String split) {
        if (str != null && !str.equals("")) {
            return str.split(split);
        }
        return null;
    }


    /**
     * 把逗号分隔字符串转换List的Long
     *
     * @param str
     * @return
     */
    public static List<Long> splitStr2LongArr(String str) {
        String[] strings = splitStr2StrArr(str,",");
        if (strings == null) return null;

        List<Long> result = new ArrayList<>();
        for (String string : strings) {
            result.add(Long.parseLong(string));
        }

        return result;
    }
    /**
     * 把逗号分隔字符串转换List的Long
     *
     * @param str
     * @return
     */
    public static List<Long> splitStr2LongArr(String str,String split) {
        String[] strings = splitStr2StrArr(str,split);
        if (strings == null) return null;

        List<Long> result = new ArrayList<>();
        for (String string : strings) {
            result.add(Long.parseLong(string));
        }

        return result;
    }

    public static String getRandomString(int length) {
        String str = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(10);
            sb.append(str.charAt(number));
        }
        return sb.toString();

    }

    // 26字母+10数字
    public static String getComplexRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    public static String convertPropertiesToHtml(String properties){
        //1:容量:6:32GB_4:样式:12:塑料壳
        StringBuilder sBuilder = new StringBuilder();
        String[] propArr = properties.split("_");
        for (String props : propArr) {
            String[] valueArr = props.split(":");
            sBuilder.append(valueArr[1]).append(":").append(valueArr[3]).append("<br>");
        }
        return sBuilder.toString();
    }

}
2.springdata-redis

A 导入jar

<!--spirngboot springdata对redis支持-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

B 配置属性

spring:
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password: 123456
    jedis:
      pool:
        max-wait: 2000ms
        min-idle: 2
        max-idle: 8

启动redis服务:找到redis安装目录,cmd运行,redis-server.exe redis.windows.conf
C 编写测试类(基于springboot的测试类(继承BaseTest即可),用springdataredis提供的bean直接操作redis)

public class RedisTest extends BaseTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test(){
        redisTemplate.opsForValue().set("ceshi", "搞一条数据");
        System.out.println(redisTemplate.opsForValue().get("ceshi"));

    }
}
3.Md5技术

不可逆加密技术,只能加密不能解密。 只能做比对,一般用来加密用户登录蜜马。
我们要做的是把传入的蜜马进行加密和然后数据库查询出来的密文进行比对判断蜜马是否正确。

盐值:同一种加密算法,由于不同的盐值,加密出来就不一样。
每个用户都有自己盐值,就算是相同的蜜马,两个用户加密出来的密文也不一样。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {

    /**
     * 加密
     * @param context  明文
     */
    public static String encrypByMd5(String context) {
        try {  
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(context.getBytes());//update处理
            byte [] encryContext = md.digest();//调用该方法完成计算

            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < encryContext.length; offset++) {//做相应的转化(十六进制)
                i = encryContext[offset];
                if (i < 0) i += 256;
                if (i < 16) buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block  
            e.printStackTrace();
            return  null;
        }  
    }

    public static void main(String[] args) {

        //1.准备需要加密的蜜马
        String pwd = "1";
        //2 准备盐值
        String salt = StrUtils.getComplexRandomString(32);
        //2.加密  + 盐
        String pwdMd5 = MD5Utils.encrypByMd5(pwd + salt);
            // 将盐值和秘文存储到数据
        System.out.println(pwdMd5);

        //模拟登陆蜜马校验
        String pwdStr = pwd;
        String saltTem = salt;//相当于从数据库查询出来
        String pwdTmpMd5 = MD5Utils.encrypByMd5(pwdStr + saltTem);
        System.out.println("==="+pwdTmpMd5);
        if(pwdTmpMd5.equals(pwdMd5)){
            System.out.println("登陆成功");
        }else{
            System.out.println("蜜马错误");
        }

    }

}
4.短信接口

http://sms.webchinese.com.cn/Rates.shtml
用户信息修改,修改短信秘钥

导入依赖包

        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>

代码应用(工具类 常量类)

	public static void sendsms(String phones, String message) throws IOException {
        HttpClient client = new HttpClient();
        PostMethod post = new PostMethod("https://utf8api.smschinese.cn/");
        post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//在头文件中设置转码
        NameValuePair[] data ={ new NameValuePair("Uid", "mingfeng"),new NameValuePair("Key", "d41d8cd98f00b204e980"),new NameValuePair("smsMob",phones),new NameValuePair("smsText",message)};
        post.setRequestBody(data);

        client.executeMethod(post);
        Header[] headers = post.getResponseHeaders();
        int statusCode = post.getStatusCode();
        System.out.println("statusCode:"+statusCode); //HTTP状态码
        for(Header h : headers){
            System.out.println(h.toString());
        }
        String result = new String(post.getResponseBodyAsString().getBytes("utf-8"));
        System.out.println(result);  //打印返回消息状态

        post.releaseConnection();
    }

发送短信验证码

前端页面准备

1.拷贝register.html到根目录,更新引用路径

2.index.html设置在新标签页打开登录界面: target=“_blank”

	<div class="menu-hd">
		<a href="#" target="_top" class="h">亲,请登录</a>
		<a href="register.html" target="_blank">免费注册</a>
	</div>

	<div class="member-logout">
		<a class="am-btn-warning btn" href="login.html">登录</a>
		<a class="am-btn-warning btn" target="_blank" href="register.html">注册</a>
	</div>

3.静态项目引入js插件vue和axios
拷贝ph-admin\node_modules里的axios和vue到ph-web/js/plugin目录里并在register.html页面引入

        <!--引入vue和axios-->
		<script src="js/plugin/vue/dist/vue.min.js"></script>
		<script src="js/plugin/axios/dist/axios.js"></script>
		<!--全局使用-->
		<script src="js/common.js"></script>
		<!-- 局部使用
		<script type="text/javascript">
            //配置axios的全局基本路径
            /*axios.defaults.baseURL='/api' 前端解决跨域*/
            axios.defaults.baseURL='http://localhost:8080/'
            //全局属性配置,在任意组件内可以使用this.$http获取axios对象
            Vue.prototype.$http = axios
		</script>-->

在js目录下新建common.js

//配置axios的全局基本路径
/*axios.defaults.baseURL='/api' 前端解决跨域*/
axios.defaults.baseURL='http://localhost:8080/'
//全局属性配置,在任意组件内可以使用this.$http获取axios对象
Vue.prototype.$http = axios

绑定div节点

<div class="am-tab-panel" id="myDiv">

写vue.js

<script type="text/javascript">
	new Vue({
		el:"#myDiv",
		mounted(){
			alert(this.$http)
		}
	})
</script>

获取的a标签换为按钮(方便置灰和显示秒数倒计时),绑定方法

<!--<a class="btn" href="javascript:void(0);" οnclick="sendMobileCode();" id="sendMobileCode">
	<span id="dyMobileButton">获取</span></a>-->
<button type="button" @click="sendMobileCode">获取</button>
		methods:{
			sendMobileCode(){
				alert(123)
			}
		},

点击获取拿到手机号

<input type="tel" v-model="phoneUserForm.phone" name="" id="phone" placeholder="请输入手机号">
<script type="text/javascript">
	new Vue({
		el:"#myDiv",
		data:{
			phoneUserForm:{
				phone:18696148335
			}
		},
		methods:{
			sendMobileCode(){
				alert(this.registerForm.phone)
			}
		},
		mounted(){
			// alert(this.$http)
		}
	})
</script>
<script type="text/javascript">
	new Vue({
		el:"#myDiv",
		data:{
			phoneUserForm:{
				phone:""
			}
		},
		methods:{
			sendMobileCode(){
				//1.判断手机号不为空
				if(!this.phoneUserForm.phone){
					alert("手机号不能为空");
					return;
				}
				//2.获取按钮 禁用按钮 发送时灰化不能使用 发送成功倒计时60才能使用 如果发送失败立即可以发送
				var sendBtn = $(event.target);
				sendBtn.attr("disabled",true);
				this.$http.post('/verifycode/smsCode',
						{"phone":this.phoneUserForm.phone}).then((res) => {
					console.log(res);
					var ajaxResult = res.data;
					if(ajaxResult.success){
						alert("手机验证码已经发送到您的手机,请在3分钟内使用");
						//3.1.发送成:倒计时
						var time = 60;
						var interval = window.setInterval( function () {
							//每一条倒计时减一
							time = time - 1 ;
							//把倒计时时间搞到按钮上
							sendBtn.html(time);
							//3.2.倒计时完成恢复按钮
							if(time <= 0){
								sendBtn.html("重发");
								sendBtn.attr("disabled",false);
								//清除定时器
								window.clearInterval(interval);
							}
						},1000);
					}else{
						//3.3.发送失败:提示,恢复按钮
						sendBtn.attr("disabled",false);
						alert("发送失败:"+ajaxResult.message);
					}
				});
			}
		},
		mounted(){
			// alert(this.$http)
		}
	})
</script>
发送短信后台
搭建用户模块

User,loginInfo
搭建完模块后记得yml配置domain和query的扫描路径(别名)文章来源地址https://www.toymoban.com/news/detail-572951.html

单独写公共可用的发短信接口
VerifycodeController
@RestController
@RequestMapping("/verifycode")
public class VerifycodeController {
    @Autowired
    private IVerifycodeService verifycodeService;

    /**
     * 发送短信验证码
     * @param phone  给谁发送  只是允许传入一个手机号
     * @return
     */
    @PostMapping("/smsCode")
    public AjaxResult sendSmsCode(@RequestBody String phone){
        try {
            verifycodeService.sendSmsCode(phone);
            return AjaxResult.me();
        } catch (BusinessException e) {
            return AjaxResult.me().setMessage("发送失败!"+e.getMessage());
        }catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setMessage("系统繁忙,稍后重试!!");
        }
    }
}
VerifycodeServiceImpl
		//1.校验
          //1.1手机号空校验
          //1.2不能被注册
        //2.判断是否存在验证码(从redis中获取电话对应的验证码)
        //2.1 存在
            //2.1.1 判断是否过了重发时间(1分钟)
                //2.1.1.1 如果没过重发时间。报错:请勿重复发送
                //2.1.1.2 如果过了,使用原来还没过期的验证码,刷新过期时间
        //2.2 不存在
           //2.2.1直接生成验证码
        //3 保存验证码到redis  设置过期时间
        //4 发送短信(使用工具类掉短信接口即可)
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class VerifycodeServiceImpl implements IVerifycodeService {
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public void sendSmsCode(String phone) {
        //1.校验
          //1.1手机号空校验
        if(!StringUtils.hasLength(phone)){
           throw new BusinessException("手机号不能为空!");
        }
          //1.2不能被注册
        User user = userService.loadUserByPhone(phone);
        if(user != null){
            throw new BusinessException("用户已经你存在!");
        }
        //2.判断是否存在验证码(从redis中获取电话对应的验证码)
        Object codeObj = redisTemplate.opsForValue().get(UserConstant.USER_VERFIY_CODE+":"+phone);
        String code = "";
        if(codeObj !=null){
            //2.1 存在
            String value =(String)codeObj;
            String timeStr = value.split(":")[1];//时间戳
            //2.1.1 判断是否过了重发时间(1分钟)
            if(System.currentTimeMillis()-Long.valueOf(timeStr) <= 1*60*1000){
                //2.1.1.1 如果没过重发时间。报错:请勿重复发送
                throw new BusinessException("请勿重复发送验证码!!!");
            }
            //2.1.1.2 如果过了,使用原来还没过期的验证码,刷新过期时间
            code = value.split(":")[0];//验证码
        }else{//2.2 不存在
            //2.2.1直接生成验证码
            code = StrUtils.getComplexRandomString(4);
        }
        //拼接存储验证码的格式
        String codeValue = code + ":" + System.currentTimeMillis();
        //3 保存验证码到redis  设置过期时间
        redisTemplate.opsForValue().set(UserConstant.USER_VERFIY_CODE+":"+phone, codeValue, 3, TimeUnit.MINUTES);
        //4 发送短信(使用工具类掉短信接口即可)
        /*SmsUtils.sendSms(phone, "您的验证码是:"+code+"; 请在3分钟内使用!");*/
        System.out.println("您的验证码是:"+code+"; 请在3分钟内使用!");
    }
}

到了这里,关于B070-项目实战-用户模块--手机注册的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • B072-项目实战-用户模块--前台登录 三方登录

    前台登录-账号登录 前端完成 1)后台登录接口(和管理员登录接口共用,以type划分) 2)前台登录实现并且保存loginInfo和token到localStorage,登录成功跳转首页,并展示用户名 3)前台通过axios的前置拦截器携带token到后台 4)后台做token的登录拦截器,如果没有回报错给前台(前

    2024年02月16日
    浏览(43)
  • Django用户认证: 利用Django Auth模块实现用户注册、登录与登出

    用户登录注册属于用户认证的一部分,Django内置了一套用户认证体系,使用起来比较方便,而且支持用户定制和拓展,足以满足任何复杂的业务需求。 Django框架中,用户权限管理被划分为三个层次: 用户 :系统使用者,拥有自己的权限。可被一个或多个用户组包含。 用户组

    2023年04月20日
    浏览(58)
  • 5G模块可以注册到4G,不能注册到5G;SIM卡接到5G手机是可以注册到5G网络的?

    AT+CGDCONT=1,“IP”,“APN” //不同运营商APN不一样,这里APN改为对应运营商的, 例如:中国移动APN:CMNET;中国联通APN:3GNET;中国电信APN:CTNET

    2024年02月12日
    浏览(75)
  • 将Cookies信息伪造成手机注册的高级用户来免费观看收费电影

    如今网络上的电影网站不少,但很多都是需收费的,很少会有免费的“午餐”等待大家前去享受,但是现在很多电影网站注册的普通会员,如果不续费,剩余钱数便为0元,此时是根本无法观看到收费电影的。 即使你是刚刚用完钱币的普通用户,也会被拒绝在无法浏览的“门

    2024年02月05日
    浏览(53)
  • Java项目实战笔记--基于SpringBoot3.0开发仿12306高并发售票系统--(二)项目实现-第二篇-前端模块搭建及单点登录的实现

    本文参考自 Springboot3+微服务实战12306高性能售票系统 - 慕课网 (imooc.com) 本文是仿12306项目实战第(二)章——项目实现 的第二篇,详细讲解使用Vue3 + Vue CLI 实现前端模块搭建的过程,同时其中也会涉及一些前后端交互的实现,因此也会开发一些后端接口;搭建好前端页面后,

    2024年03月26日
    浏览(58)
  • C++入门: 类和对象笔记总结(上)

     C语言是 面向过程 的, 关注 的是 过程 ,分析出求解问题的步骤,通过函数调用逐步解决问题。  C++是基于 面向对象 的, 关注 的是 对象 ,将一件事情拆分成不同的对象,靠对象之间的交互完成。   C语言结构体中只能定义变量,在C++中,结构体升级成类内不仅可以定

    2024年02月07日
    浏览(43)
  • Django实现用户注册登录,表单提交后跳转网页(学习笔记)

    效果图如下:   使用命令提示符,进入想存放项目的目录: 在项目coco目录下新建static文件夹,用于存放网页文件的css,js,imgs 在coco_app目录下新建文件夹templates,用于存放需要用到的HTML网页 打开coco文件夹中的settings.py注册coco_app 引用templates 连接数据库,这里我用的MySQL数据

    2023年04月11日
    浏览(82)
  • JavaWeb项目----实现用户登录、注册、对商品信息进行的添加、删除、修改功能

    在idea中创建有关类   web中写jsp页面,index.jsp是首页布局 运行效果如下:  登录页面 运行效果如下:   注册页面  运行效果如下:   登陆正确时跳转到zhuye.jsp主页页面( 使用Java脚本获取集合中对象的元素,放html标签中) 运行效果如下:   在登陆页面,密码或用户名输入

    2024年02月11日
    浏览(40)
  • WPF实战学习笔记13-创建注册登录接口

    添加文件 创建文件 + MyToDo.Api ​ ./Controllers/LoginController.cs ​ ./Service/ILoginService.cs ​ ./Service/LoginService.cs MyToDo.Share ./Dtos/UserDto.cs LoginController.cs ILoginService.cs LoginService.cs UserDto.cs 依赖注入 Program.cs 添加 AutoMapperProfilec.s 添加

    2024年02月15日
    浏览(39)
  • WPF实战学习笔记30-登录、注册服务添加

    添加注册数据类型 添加注册UI 修改bug UserDto的UserName更改为可null类型 Resgiter 添加加密方法 修改控制器 添加注册数据类型 添加文件MyToDo.Share.Models.ResgiterUserDto.cs 添加注册UI 修改文件:Mytodo.Views.LoginView.xaml 添加注册、登录、退出等功能实现以及功能的字段 修改bug UserDto的User

    2024年02月14日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包