Java学习Day53:铲除紫云山金丹原料厂厂长(手机快速登录、权限控制)

1.手机快速登录

手机快速登录功能,就是通过短信验证码的方式进行登录。这种方式相对于用户名密码登录方式,用户不需要记忆自己的密码,只需要通过输入手机号并获取验证码就可以完成登录,是目前比较流行的登录方式。

前端页面:

        <!-- 页面内容 --><div class="contentBox"><div class="login"><form id='login-form'><div class="input-row"><label>手机号</label><div class="loginInput"><input v-model="loginInfo.telephone" id='account' type="text" placeholder="请输入手机号"><input id="validateCodeButton" @click="sendValidateCode()" type="button" style="font-size: 12px" value="获取验证码"></div></div><div class="input-row"><label>验证码</label><div class="loginInput"><input v-model="loginInfo.validateCode" style="width:80%" id='password' type="password" placeholder="请输入验证码"></div></div><div class="input-row" style="font-size: 12px"><input type="checkbox" checked>阅读并同意《瑞通健康用户协议》《瑞通健康隐私条款》</div><div class="btn yes-btn"><a @click="login()" href="#">登录</a></div></form></div></div>
                //发送验证码sendValidateCode(){if (this.loginInfo.telephone==undefined){this.$message.error("手机号为空!")return;}ref=/^1[3-9][0-9]{9}$/;if (!ref.test(this.loginInfo.telephone)){this.$message.error("请输入格式正确的手机号!")return;}let num=30;let btn=$("#validateCodeButton");let id=setInterval(function (){num--;btn.attr("disabled",true)btn.val(num+"秒后再次发送!")if (num==0){btn.attr("disabled",false)btn.val("获取验证码")clearInterval(id)}},1000)axios.get("/LoginController/loginPhone.do?telephone="+this.loginInfo.telephone).then(response=>{if (response.data.flag){console.log(response.data.data)}})},

依旧使用正则表达式判断输入的正确性,每个判断后使用return避免提示被击穿!

选择按钮也是用jQuery实现选择;

SetInterVal计时器实现倒计时;

后端:

@GetMapping("/loginPhone")public Result loginPhone(String telephone){Integer capstr= ValidateCodeUtils.generateValidateCode(4);Jedis jedis=jedisPool.getResource();jedis.setex(telephone+ RedisConstant.SENDTYPE_ORDER,60*60*60, String.valueOf(capstr));jedis.close();return new Result(true,"success",capstr);}

生成验证码,使用暂存存入Redis,键位手机号加上预约类型,时间为秒计时,验证码由工具类生成;

结束关闭Jedis;(省略验证码环节!)

前端登陆判断:

 login(){if (this.loginInfo.telephone==undefined){this.$message.error("手机号为空!")return;}ref=/^1[3-9][0-9]{9}$/;if (!ref.test(this.loginInfo.telephone)){this.$message.error("请输入格式正确的手机号!")return;}if (this.loginInfo.validateCode==undefined){this.$message.error("请输入验证码!")return;}axios.post("/LoginController/loginJudge.do",this.loginInfo).then(response=>{if (response.data.flag){this.$message.success(response.data.message)}else {this.$message.error(response.data.message)}})}

后端:

 @PostMapping("/loginJudge")public Result loginJudge(@RequestBody Map<String ,Object> objectMap, HttpServletResponse response){String telephone= (String) objectMap.get("telephone");String validateCode = (String) objectMap.get("validateCode");Jedis jedis = jedisPool.getResource();//手机号+Redis的常量为键,取出Redis数据中保存的验证码String redisCode = jedis.get(telephone+ RedisConstant.SENDTYPE_ORDER);if (redisCode == null){//验证失败return new Result(false, "验证码过期");}//判断验证码是否相等if (!validateCode.equals(redisCode)){//验证失败return new Result(false, MessageConstant.VALIDATECODE_ERROR);}Cookie cookie=new Cookie("telphone",telephone);cookie.setMaxAge(60*60*24*60);cookie.setPath("/");response.addCookie(cookie);Member a =memberMapper.ifMember(telephone);Result result = null;if (a==null){a=new Member();a.setPhoneNumber(telephone);int res= memberMapper.addMember(a);if (res!=0){result= new Result(true,"会员自动注册成功!");}else {result= new Result(false,"会员自动注册失败!");}}else {result=new Result(true,"会员登录!");}return result;}

1.通过手机号,判断Redis的验证码对比是否一样;

2.设置Cookie,增加用户体验,以便下次登陆时手机号自动添加;

将Cookie返回前端后,前端是键值对形式,需要切割使用,前端在挂载时拿到数据,就可以先一步显示;

 mounted(){let cookie = document.cookie.split("=")[1];console.log(cookie)if (cookie != undefined){// $("#account").val(cookie);document.getElementById("account").value = cookie//发送请求,提交cookie == 手机号this.loginInfo.telephone = cookie}
}

Cookie 是一种小型数据文件,通常由网站在用户的浏览器中存储,用于多种目的。以下是 cookie 的一些主要作用:

  1. 会话管理:Cookie 可以存储用户的登录状态,方便用户在网站上保持登录,免去每次访问时都要输入用户名和密码的麻烦。

  2. 个性化设置:网站可以通过 Cookie 保存用户的偏好设置,比如语言、主题、布局等,提供更个性化的浏览体验。

  3. 追踪和分析:Cookie 可以用于收集用户的浏览行为数据,帮助网站分析流量、优化内容和改进用户体验。

  4. 广告投放:许多网站使用 Cookie 来记录用户的兴趣和行为,以便为其提供更相关的广告内容。

  5. 购物车功能:在电商网站上,Cookie 可以帮助记住用户在购物车中添加的商品,即使用户离开网站,重新访问时也能找到之前的选择。

总之,Cookie 在提升用户体验、提供个性化服务和帮助网站运营方面发挥着重要作用。

2.权限控制

现阶段Java框架实现分权限登录至少需要五张表

第一张表是用户表t_user ,第二张表是角色表t_role ,第三张表是权限表t_permission ,因为用户与角色是多对多,角色和权限是多对多,所以我们还想需要两张中间表,以上;

本案例使用Spring Security来实现权限管理;

1.创建health_Security模块,使用webapp模板,配置文件参考spring MVC;

提供index.html页面,内容为hello Spring Security!!

2.在spring-security.xml中主要配置Spring Security的拦截规则
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xmlns:security="http://www.springframework.org/schema/security"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd
">
<context:component-scan base-package="com.home"/><mvc:annotation-driven><mvc:path-matching suffix-pattern="true"/></mvc:annotation-driven><!--配置 security 要求拦截的访问资源pattern 拦截地址access hasRole('ADMIN') 需要角色,管理员角色,不拦截--><!--匿名访问,不拦截--><security:http security="none" pattern="/a.html"/><security:http security="none" pattern="/login.html"/><!--intercept-url:定义一个拦截规则pattern:对哪些url进行权限控制access:在请求对应的URL时需要什么权限,默认配置时它应该是一个以逗号分隔的角色列表,请求的用户只需拥有其中的一个角色就能成功访问对应的URL--><security:http auto-config="true" use-expressions="true"><security:intercept-url pattern="/index.jsp" access="hasRole('ROLE_ADMIN')"></security:intercept-url><security:form-login login-page="/login.html" default-target-url="/a.html"authentication-failure-url="/login.html"username-parameter="username" password-parameter="password" login-processing-url="/login.do"/><security:csrf disabled="true"></security:csrf></security:http><!--认证管理器--><security:authentication-manager><!--自定义登录认证--><security:authentication-provider user-service-ref="userSecurity"><!--配置登录的账户和密码,框架提供登录页面的-->
<!--            <security:user-service>--><!--登录账户的名字 admin,角色admin,密码{noop}密码是明文的,不加密的密码-->
<!--            <security:user name="admin" authorities="ROLE_ADMIN" password="{noop}admin"/>-->
<!--            </security:user-service>--></security:authentication-provider></security:authentication-manager><bean class="com.home.security.UserSecurity" id="userSecurity"></bean></beans>
1、项目中我们将所有的资源(所有请求URL)都保护起来,实际环境下往往有一些资源不需要认证也可以访问,也就是可以匿名访问。
<!--http:用于定义相关权限控制指定哪些资源不需要进行权限校验,可以使用通配符
-->
<security:http security="none" pattern="/pages/a.html" />
<security:http security="none" pattern="/paegs/b.html" />
<security:http security="none" pattern="/pages/**"></security:http>

通过上面的配置可以发现,pages目录下的文件可以在没有认证的情况下任意访问。

2、登录页面是由框架生成的,而我们的项目往往会使用自己的登录页面。
<html>
<head><title>登录</title>
</head>
<body><form action="/login.do" method="post">username:<input type="text" name="username"><br>password:<input type="password" name="password"><br><input type="submit" value="submit"></form>
</body>
</html>

第二步:修改spring-security.xml文件,指定login.html页面可以匿名访问

<security:http security="none" pattern="/login.html" />

第三步:修改spring-security.xml文件,加入表单登录信息的配置

    <security:http auto-config="true" use-expressions="true"><security:intercept-url pattern="/index.jsp" access="hasRole('ROLE_ADMIN')"></security:intercept-url><security:form-login login-page="/login.html" default-target-url="/a.html"authentication-failure-url="/login.html"username-parameter="username" password-parameter="password" login-processing-url="/login.do"/><security:csrf disabled="true"></security:csrf></security:http>
3、直接将用户名和密码配置在了配置文件中,而真实生产环境下的用户名和密码往往保存在数据库中。

在后端取用数据库的数据

本案例使用Map模拟

public class UserSecurity implements UserDetailsService {private Map<String, User> map = new HashMap<>();public void initdata(){map.put("viki",new User("viki","123"));map.put("jiajun",new User("jiajun","456"));}@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {initdata();//用户名为 键,取出Map中的集合User user = map.get(username);if(user == null){return null;}//取出密码String password ="{noop}"+ user.getPw();//返回UserDetails 对象//User对象构造方法,用户名,密码,授权数据//授权数据:Collection<? extends GrantedAuthority> authorities)List<GrantedAuthority> list = new ArrayList<>();//集合添加GrantedAuthority子类对象list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));UserDetails userDetails = new org.springframework.security.core.userdetails.User(username,password,list);return userDetails;}
}
4、在配置文件中配置的密码使用明文,这非常不安全,而真实生产环境下密码需要进行加密。

前面我们使用的密码都是明文的,这是非常不安全的。一般情况下用户的密码需要进行加密后再保存到数据库中。

常见的密码加密方式有:

3DES、AES、DES:使用对称加密算法,可以通过解密来还原出原始密码

MD5、SHA1:使用单向HASH算法,无法通过计算还原出原始密码,但是可以建立彩虹表进行查表破解

bcrypt:将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题

加密后的格式一般为:

$2a$10$/bTVvqqlH9UiE0ZJZ7N2Me3RIgUCdgMheyTgV0B4cMCSokPa.6oCa

加密后字符串的长度为固定的60位。其中:$是分割符,无意义;2a是bcrypt加密版本号;10是cost的值;而后的前22位是salt值;再然后的字符串就是密码的密文了。

配置文件:

public class MD5Utils {/*** 使用md5的算法进行加密*/public static String md5(String plainText) {byte[] secretBytes = null;try {secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());} catch (NoSuchAlgorithmException e) {throw new RuntimeException("没有md5这个算法!");}String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字// 如果生成数字未满32位,需要前面补0for (int i = 0; i < 32 - md5code.length(); i++) {md5code = "0" + md5code;}return md5code;}
}
public class TestMD5 {public static void main(String[] args) {String string = MD5Utils.md5("shisong123");//21232f297a57a5a743894a0e4a801fc3  == admin//e00cf25ad42683b3df678c61f42c6bda  == admin1//0e750f2372908783b76cd1f1aa62b0b6  == nihao888System.out.println("string = " + string);}
}

使用工具类加密即可!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/458124.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Halcon 多相机统一坐标系(标定)

多相机统一坐标系是指将多个不同位置的相机的图像采集到同一个坐标系下进行处理和分析的方法。 在计算机视觉和机器视觉领域中&#xff0c;多相机统一坐标系被广泛应用于三维重建、立体视觉、目标跟踪等任务中。 以gen_binocular_rectification_map&#xff08;生成描述图像映…

Python条形图 | 指标(特征)重要性图的绘制

在数据科学和机器学习的工作流程中&#xff0c;特征选择是一个关键步骤。通过评估每个特征对模型预测能力的影响&#xff0c;我们可以选择最有意义的特征&#xff08;指标&#xff09;&#xff0c;从而提高模型的性能并减少过拟合。本文将介绍如何使用 Python 的 Seaborn 和 Ma…

Vue.js 组件开发教程:从基础到进阶

Vue.js 组件开发教程:从基础到进阶 引言 在现代前端开发中,Vue.js 作为一款流行的 JavaScript 框架,以其简单易用和灵活性赢得了开发者的青睐。Vue 组件是 Vue.js 的核心概念之一,理解组件的开发和使用对构建复杂的用户界面至关重要。本篇文章将详细介绍 Vue.js 组件的开…

spygalss cdc 检测的bug(二)

当allow_qualifier_merge设置为strict的时候&#xff0c;sg是要检查门的极性的。 如果qualifier和src经过与门汇聚&#xff0c;在同另一个src1信号或门汇聚&#xff0c;sg是报unsync的。 假设当qualifier为0时&#xff0c;0&&src||src1src1&#xff0c;src1无法被gat…

SSM学习day01 JS基础语法

一、JS基础语法 跟java有点像&#xff0c;但是不用注明数据类型 使用var去声明变量 特点1&#xff1a;var关键字声明变量&#xff0c;是为全局变量&#xff0c;作用域很大。在一个代码块中定义的变量&#xff0c;在其他代码块里也能使用 特点2&#xff1a;可以重复定义&#…

好用的idea插件之自动sql生成

功能 自动化代码生成&#xff1a; 通过解析数据库表结构和实体类定义&#xff0c;自动生成对应的Mapper接口、XML映射文件、Service、DAO和实体类等代码。支持快速生成增删查改&#xff08;CRUD&#xff09;代码&#xff0c;以及在表结构变化后重新生成代码而不覆盖自定义方法。…

#【2024年10月26日更新】植物大战僵尸杂交本V2.6更新内容与下载

更新内容 新增植物&#xff1a; 英雄植物&#xff1a;终极射手、向日葵公主、汉堡王&#xff08;仅限英雄模式使用&#xff09;。星卡植物&#xff1a;星星盒子、猫窝、迷幻投手、玉米旋转机&#xff08;需要一定数量的星星解锁&#xff09;。挑战植物&#xff1a;金卡黄金锤子…

什么是 VolTE 中的 Slient Redial?它和 CSFB 什么关系?

目录 1. 什么是 Silent Redial(安静的重拨号)? 2. Silent Redial 信令流程概述 3. 总结 Silent Redial 和 CSFB 啥关系? 博主wx:yuanlai45_csdn 博主qq:2777137742 想要 深入学习 5GC IMS 等通信知识(加入 51学通信),或者想要 cpp 方向修改简历,模拟面试,学习指导都…

FreeSWITCH 简单图形化界面30 - 使用MYODBC时可能遇到的错误

FreeSWITCH 简单图形化界面30 - 使用MYODBC时可能遇到的错误 测试环境1、 MYODBC 3.51.18 or higher2、分析和解决2.1 解决1&#xff0c;降级MySQL ODBC2.2 解决2&#xff0c;修改FreeSWITCH代码 测试环境 http://myfs.f3322.net:8020/ 用户名&#xff1a;admin&#xff0c;密…

【学术论文投稿】Windows11开发指南:打造卓越应用的必备攻略

【IEEE出版南方科技大学】第十一届电气工程与自动化国际会议&#xff08;IFEEA 2024)_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 一、Windows11开发环境搭建 二、Windows11关键新特性 三、Windows11设计指南 …

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-21

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-21 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-21目录1. The Fair Language Model Paradox摘要研究背景问题与挑战如何解决创新点算法模型实验效果重要数据与结论推荐阅读指数&…

Spring Boot:植物健康监测的智能先锋

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了植物健康系统的开发全过程。通过分析植物健康系统管理的不足&#xff0c;创建了一个计算机管理植物健康系统的方案。文章介绍了植物健康系统的系统分析部分&…

基于Python的B站视频数据分析与可视化

基于Python的B站视频数据分析与可视化 爬取视频、UP主信息、视频评论 功能列表 关键词搜索指定帖子ID爬取指定UP主的主页爬取支持评论爬取生成评论词云图支持数据存在数据库支持可视化 部分效果演示 爬取的UP主信息 关键词搜索爬取 指定UP主的主页爬取 指定为黑马的了 爬取视…

嵌入式C语言字符串具体实现

大家好,今天主要给大家分享一下,如何使用C语言进行字符串操作与实现。 第一:字符串相关操作实现 复制函数五个基本要素: 头文件:#include <string.h> 函数原型:strcpy(char dest[],char src[]) -----string copy 功能:把src数组中\0之前的所有字符,连同‘\…

Http 状态码 301 Permanent Rediret 302 Temporary Redirect

HTTP状态码301和302是什么&#xff1f; 1、HTTP状态码301 HTTP状态码301表示永久性转移&#xff08;Permanent Redirect&#xff09;&#xff0c;这意味着请求的资源已经被分配了一个新的URI&#xff0c;以后的引用应该使用资源现在所指的URI。 HTTP 301状态码表示请求的资源…

工具方法 - Omnifocus: 网页版基本操作

1&#xff0c;第一个左上角点开&#xff0c;显示如下的视角&#xff1a; 从这个工具来说&#xff0c;优先的第一事项&#xff0c;是用户从哪个视角来切入&#xff0c;不同的视角展现不同的逻辑&#xff0c;对应不同的操作。 通过视角一级的菜单&#xff0c;来方便用户的操作。 …

2024.10.9华为留学生笔试题解

第一题无线基站名字相似度 动态规划 考虑用动态规划解决 char1=input().strip() char2=input().strip() n,m=len(char1),len(char2) dp=[[0]*(m+1) for _ in range(n+1)] #dp[i][j]定义为以i-1为结尾的char1 和以 j-1为结尾的char2 的最短编辑距离 setA = set(wirel@com) set…

解决pycharm无法添加conda环境的问题【Conda Environment下没有Existing environment】

解决pycharm无法添加conda environment 问题【Conda Environment下不显示Existing environment】 问题&#xff1a; 第一次下载好pycharm准备编写代码&#xff0c;在Anoconda Prompt建立好环境后&#xff0c;打开pycharm导入环境&#xff0c;却发现在【Conda Environment】处…

C++STL之stack

1.stack的使用 函数说明 接口说明 stack() 构造空的栈 empty() 检测 stack 是否为空 size() 返回 stack 中元素的个数 top() 返回栈顶元素的引用 push() 将元素 val 压入 stack 中 pop() 将 stack 中尾部的元素弹出 2.stack的模拟实现 #include<vector> namespace abc { …

hcia复习篇

计算机网络&#xff1a; 云技术&#xff1a; 云储存---将数据通过计算机网络传输并储存在第三方服务器。&#xff08;百度网盘&#xff09; 云计算---分布式计算。&#xff08;即共享硬件资源&#xff09; 计算机技术&#xff1a; 文字、图片、视频等---抽象文字。 抽象语言…