700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > SpringBoot——短信发送 手机验证码登录

SpringBoot——短信发送 手机验证码登录

时间:2018-11-09 01:49:35

相关推荐

SpringBoot——短信发送 手机验证码登录

目录

一、短信发送

1.1 阿里云短信服务

1.1.1 设置短信签名

1.1.2 模板管理

1.1.3 设置AccessKey

1.2 短信发送——代码开发

1.2.1 导入maven坐标

1.2.2 调用API

1.2 手机验证码登录

1.2.1 用户数据库表

1.2.2 修改过滤器

1.2.3 随机生成验证码的工具类

1.2.4手机验证码登录-- 发送验证码

1.2.5手机验证码登录-- 验证验证码

一、短信发送

1.1 阿里云短信服务

短信服务_企业短信营销推广_验证码通知-阿里云

也可以在下面这个地方查看短信服务

1.1.1 设置短信签名

短信签名就是短信发送者的署名,表示发送方的身份

1.1.2 模板管理

申请下来之后可以点击详情进行查看

其中模板CODE是自动生成的,不用管,重点是模板的内容

1.1.3 设置AccessKey

创建新的用户

勾选上之后,我们在编程代码中就能使用

当我们创建用户成功后,就生成了一对AccessKey,即AccessKey ID(用户名) 与AccessKey Secret(密码)

很多人在这里的时候不小心没截图或者没保存就关了,丢失了AccessKey,但是不要紧,还可以再次创建

还有就是如果别人知道了我们的AccessKey,那别人使用的时候会就花我们的钱。我们也可以把泄露的AccessKey禁用

之后再新增授权。这次授权的意思就是仅仅授予有关短信服务的,即是我们泄露了,别人也只能操作短信服务,对我们的影响很小。

1.2 短信发送——代码开发

参照官方文档即可

新手指引_短信服务-阿里云帮助中心

1.2.1 导入maven坐标

<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.5.16</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>2.1.0</version></dependency>

1.2.2 调用API

/*** 短信发送工具类*/public class SMSUtils {/*** 发送短信* @param signName 签名* @param templateCode 模板* @param phoneNumbers 手机号* @param param 参数*/public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param){DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAI5tHRxs2FeCu5JcJTGbm2", "v0H4PaJpXSwNr6XChtlVYAgmQWgKRA");IAcsClient client = new DefaultAcsClient(profile);SendSmsRequest request = new SendSmsRequest();request.setSysRegionId("cn-hangzhou");// 要发送给那个人的电话号码request.setPhoneNumbers(phoneNumbers);//我们在阿里云设置的签名request.setSignName(signName);// 我们在阿里云设置的模板request.setTemplateCode(templateCode);// 在设置模板的时候有一个占位符request.setTemplateParam("{\"code\":\""+param+"\"}");//request.setPhoneNumbers("1368846****");//接收短信的手机号码//request.setSignName("阿里云");//短信签名名称//request.setTemplateCode("SMS_20933****");//短信模板CODE//request.setTemplateParam("张三");//短信模板变量对应的实际值try {SendSmsResponse response = client.getAcsResponse(request);System.out.println("短信发送成功");}catch (ClientException e) {e.printStackTrace();}}}

1.2 手机验证码登录

方便、快捷、无需注册、直接登陆使用短信验证码作为登录凭证,无序记忆密码安全

登录流程: 输入手机号 -> 获取验证码 -> 输入验证码 -> 点击登录 -> 登陆成功

注意: 通过手机验证码登录,手机号是区分不同用户的标识

1.2.1 用户数据库表

因为是通过手机和验证码登录的,所以没有用户名和密码字段

1.2.2 修改过滤器

在写代码之前记得要在过滤器中定义不需要处理的请求路径/user/sendMsg和/user/login

然后访问路径:http://localhost:8080/front/page/login.html

/*** 检查用户是否已经完成登录* 过滤器与拦截器的区别:Filter对所有访问进行增强(在Tomcat服务器进行配置),Interceptor仅针对SpringMVC的访问进行增强*/@Slf4j@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*") //urlPatterns指定拦截哪些路径public class LoginCheckFilter implements Filter {// 此对象的作用:路径匹配器, 匹配路径时支持通配符public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//servletRequest向下强制类型转换HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//1. 获取本次请求的URI( URI:请求的资源路径)String requestURI = request.getRequestURI();log.info("拦截到请求:{}", request.getRequestURI());// 定义不用处理的请求路径String[] urls = new String[]{"/employee/login","/employee/logout","/backend/**","/front/**","/common/**","/user/sendMsg","/user/login"};//2. 判断本次请求是否需要处理(因为有些请求并不需要用户登录)boolean check = check(requestURI, urls);//3.如果不需要处理,则直接放行if (check) {log.info("本次请求{}不需要处理", request.getRequestURI());filterChain.doFilter(request, response);return;}//4-1.判断登录状态,如果已登录,则直接放行.从session中获取用户,如果获取到说明已经登录if (request.getSession().getAttribute("employee") != null) {log.info("用户已登录,用户id为{}", request.getSession().getAttribute("employee"));Long empId = (Long) request.getSession().getAttribute("employee");BaseContext.setCurrentId(empId);filterChain.doFilter(request, response);return;}//4-2.判断登录状态,如果已登录,则直接放行.从session中获取用户,如果获取到说明已经登录if (request.getSession().getAttribute("user") != null) {log.info("用户已登录,用户id为{}", request.getSession().getAttribute("user"));Long userId = (Long) request.getSession().getAttribute("user");BaseContext.setCurrentId(userId);filterChain.doFilter(request, response);return;}//5.如果未登录则返回未登录结果log.info("资源路径路径:{},用户未登录{}", request.getRequestURI(), request.getSession().getAttribute("employee"));// 通过输出流的方式向客户端响应数据 (为什么要返回这个NOTLOGIN? 因为前端需要这个来进行判定是否登录)response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));// filterChain.doFilter(request, response); 加上这个就无法实现}/*** 检查本次请求是否需要放行** @param requestURI 请求的资源路径* @param urls 放过的路径* @return true 放行*/public boolean check(String requestURI, String[] urls) {for (String url : urls) {boolean match = PATH_MATCHER.match(url, requestURI);if (match) {// 放行return true;}}return false;}}

1.2.3 随机生成验证码的工具类

/*** 随机生成验证码工具类*/public class ValidateCodeUtils {/*** 随机生成验证码* @param length 长度为4位或者6位* @return*/public static Integer generateValidateCode(int length){Integer code =null;//长度为4if(length == 4){code = new Random().nextInt(9999);//生成随机数,最大为9999if(code < 1000){code = code + 1000;//保证随机数为4位数字}//长度为6}else if(length == 6){code = new Random().nextInt(999999);//生成随机数,最大为999999if(code < 100000){code = code + 100000;//保证随机数为6位数字}// 其他情况}else{throw new RuntimeException("只能生成4位或6位数字验证码");}return code;}/*** 随机生成指定长度字符串验证码* @param length 长度* @return*/public static String generateValidateCode4String(int length){Random rdm = new Random();String hash1 = Integer.toHexString(rdm.nextInt());String capstr = hash1.substring(0, length);return capstr;}}

1.2.4手机验证码登录-- 发送验证码

两次ajax请求:

1. 登录页面输入手机号,点击【获取验证码】按钮,页面发送ajax请求,在服务端调用短信服务API给指定手机号发送验证码短信

2. 在登录页面输入验证码,点击【登录】按钮,发送ajax请求,在服务端处理登录请求

@PostMapping("/sendMsg")public R<String> sendMsg(@RequestBody User user, HttpSession session){//1.获取手机号String phone = user.getPhone();if(StringUtils.isEmpty(phone)){return R.error("短信发送失败");}//2.随机生成四位验证码String code = ValidateCodeUtils.generateValidateCode(4).toString();//3.调用阿里云提供的短信服务SMSUtils.sendMessage("张靖奇","",phone,code);//4.需要将生成的验证码保存到session中session.setAttribute(phone,code);return R.success("验证码短信发送成功");}

1.2.5手机验证码登录-- 验证验证码

// 其实传过来的phone:xxxx,code:xxx 也可以用map集合接收@PostMapping("/login")public R<User> login(@RequestBody Map map, HttpSession session) {log.info(map.toString());//1. 获取手机号String phone = map.get("phone").toString();//2. 获取验证码String code = map.get("code").toString();//3. 从Session中获取保存的验证码Object codeInSession = session.getAttribute(phone);//4. 进行验证码比对(页面提交的验证码和Session中保存的验证码比对)if (codeInSession != null && codeInSession.equals(code)) {//5.对比成功,说明登录成功LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getPhone,phone);User user = userService.getOne(queryWrapper);if (user==null){//6. 如果新用户,自动注册user = new User();user.setPhone(phone);user.setStatus(1);userService.save(user);}session.setAttribute("user",user.getId());return R.success(user);}return R.error("登录失败");}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。