Spring Security构建Rest服务-0801-短信验证码发送
实现短信验证码登录
开发短信验证码接口
校验短信验证码并登录
短信验证码和图片验证码开发思路类似:
1,我们访问一个controller
2,在controller里调用短信验证码生成接口生成验证码
3,验证码存进session
4,从请求里获取手机号,调用短信发送服务商的接口,给手机号发送短信
主要代码:
1,短信验证码Controller:
package com.imooc.security.core.validate.code; import java.io.IOException; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest; import com.imooc.security.core.properties.SecurityProperties;
import com.imooc.security.core.validate.code.sms.SmsCodeSender; /**
* 验证码Control
* ClassName: ValidateCodeController
* @Description: TODO
* @author lihaoyang
* @date 2018年3月1日
*/
@RestController
public class ValidateCodeController { public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; // @Autowired
// private SecurityProperties securityProperties; @Autowired
private ValidateCodeGenerator imageCodeGenerator;//图片验证码 @Autowired
private ValidateCodeGenerator smsCodeGenerator;//短信验证码 //获取session
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); @Autowired
private SmsCodeSender smsCodeSender; //短信验证码发送接口 /**
* 短信验证码
* @Description: TODO
* @param @param request
* @param @param response
* @param @throws IOException
* @return void
* @throws ServletRequestBindingException
* @throws
* @author lihaoyang
* @date 2018年3月7日
*/
@GetMapping("/verifycode/sms")
public void createSmsCode(HttpServletRequest request,HttpServletResponse response) throws Exception{ //调验证码生成接口方式
ValidateCode smsCode = smsCodeGenerator.generator(new ServletWebRequest(request));
sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, smsCode);
//获取手机号
String mobile = ServletRequestUtils.getRequiredStringParameter(request, "mobile");
//发送短信验证码
smsCodeSender.send(mobile, smsCode.getCode());
} }
短信验证码生成实现类,实现验证码接口,验证码的长度和过期时间做成可配置的,灵活些:
package com.imooc.security.core.validate.code; import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest; import com.imooc.security.core.properties.SecurityProperties; /**
* 短信验证码生成类
* ClassName: ImageCodeGenerator
* @Description: TODO
* @author lihaoyang
* @date 2018年3月2日
*/
@Component("smsCodeGenerator")
public class SmsCodeGenerator implements ValidateCodeGenerator { @Autowired
private SecurityProperties securityProperties; @Override
public ValidateCode generator(ServletWebRequest request) {
//生成验证码,长度从配置读取
String code = RandomStringUtils.randomNumeric(securityProperties.getCode().getSms().getLength());
return new ValidateCode(code, securityProperties.getCode().getSms().getExpireIn());
} public SecurityProperties getSecurityProperties() {
return securityProperties;
} public void setSecurityProperties(SecurityProperties securityProperties) {
this.securityProperties = securityProperties;
} }
验证码类:只有code和过期时间即可
package com.imooc.security.core.validate.code; import java.awt.image.BufferedImage;
import java.time.LocalDateTime;
import java.time.LocalTime; /**
* 短信验证码
* ClassName: ImageCode
* @Description: 验证码
* @author lihaoyang
* @date 2018年3月1日
*/
public class ValidateCode { private String code; private LocalDateTime expireTime;//过期时间点 /**
*
* <p>Description: </p>
* @param image
* @param code
* @param expireTn 多少秒过期
*/
public ValidateCode(String code, int expireTn) {
this.code = code;
//过期时间=当前时间+过期秒数
this.expireTime = LocalDateTime.now().plusSeconds(expireTn);
} public ValidateCode(String code, LocalDateTime expireTime) {
this.code = code;
this.expireTime = expireTime;
} /**
* 验证码是否过期
* @Description: 验证码是否过期
* @param @return true 过期,false 没过期
* @return boolean true 过期,false 没过期
* @throws
* @author lihaoyang
* @date 2018年3月2日
*/
public boolean isExpired(){
return LocalDateTime.now().isAfter(expireTime);
} public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} public LocalDateTime getExpireTime() {
return expireTime;
} public void setExpireTime(LocalDateTime expireTime) {
this.expireTime = expireTime;
} }
验证码发送抽象成接口:
package com.imooc.security.core.validate.code.sms; /**
* 短信验证码发送接口
* ClassName: SmsCodeSender
* @Description: TODO
* @author lihaoyang
* @date 2018年3月7日
*/
public interface SmsCodeSender { /**
* 发送验证码短信
* @Description: 短信发送
* @param @param mobile 接收验证码的手机号
* @param @param code 验证码
* @return void
* @throws
* @author lihaoyang
* @date 2018年3月7日
*/
void send(String mobile,String code);
}
提供一个默认实现:做成引用该模块可覆盖默认实现的,更灵活
package com.imooc.security.core.validate.code.sms; /**
* 默认的短信验证码发送类
* ClassName: DefaultSmsCodeSender
* @Description: TODO
* @author lihaoyang
* @date 2018年3月7日
*/
public class DefaultSmsCodeSender implements SmsCodeSender{ @Override
public void send(String mobile, String code) {
System.err.println("向手机 :"+mobile+" 发送短信验证码 :"+code);
} }
配置验证码生成器为spring的bean,,如果spring容器有该SmsCodeSender 接口的实现就用,没有了再配置,即可覆盖
package com.imooc.security.core.validate.code; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.imooc.security.core.properties.SecurityProperties;
import com.imooc.security.core.validate.code.sms.DefaultSmsCodeSender;
import com.imooc.security.core.validate.code.sms.SmsCodeSender; /**
* 配置验证码生成接口ValidateCodeGenerator的实际实现类的Bean
* ClassName: ValidateCodeBeanConfig
* @Description:
* 配置验证码生成接口ValidateCodeGenerator的实际实现类的Bean
* 如图片验证码的实现、短信验证码的实现
* @author lihaoyang
* @date 2018年3月5日
*/
@Configuration
public class ValidateCodeBeanConfig { @Autowired
private SecurityProperties securityProperties; /**
* @Description:
* 配置图片验证码生成bean
* @ConditionalOnMissingBean注解意思是当spring容器不存在imageCodeGenerator时才给配置一个该bean
* 作用是使程序更具可扩展性,该配置类是配置在core模块,这就意味着,如果引用该模块的项目
* 如果有一个自己的实现,实现了ValidateCodeGenerator接口,定义了自己的实现,名字也叫imageCodeGenerator时,
* 就用应用级别的实现,没有的话就用这个默认实现。
* @param @return
* @return ValidateCodeGenerator
* @throws
* @author lihaoyang
* @date 2018年3月5日
*/
@Bean
@ConditionalOnMissingBean(name="imageCodeGenerator")
public ValidateCodeGenerator imageCodeGenerator(){
ImageCodeGenerator codeGenerator = new ImageCodeGenerator();
codeGenerator.setSecurityProperties(securityProperties);
return codeGenerator;
} /**
* 配置短信验证码生成bean
* @Description:
* @param @return
* @return SmsCodeSender
* @throws
* @author lihaoyang
* @date 2018年3月7日
*/
@Bean
@ConditionalOnMissingBean(SmsCodeSender.class)
public SmsCodeSender smsCodeSender(){
return new DefaultSmsCodeSender();
}
}
验证码长度、过期时间配置类 SmsCodeProperties:
package com.imooc.security.core.properties; /**
* 短信验证码配置类
* ClassName: ImageCodeProperties
* @Description: 图片验证码配置类
* @author lihaoyang
* @date 2018年3月2日
*/
public class SmsCodeProperties { //验证码字符个数
private int length = 4;
//过期时间
private int expireIn = 60; private String url; //拦截的url public int getLength() {
return length;
} public void setLength(int length) {
this.length = length;
} public int getExpireIn() {
return expireIn;
} public void setExpireIn(int expireIn) {
this.expireIn = expireIn;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} }
登录表单:
短信 登录 <br>
<form action="/authentication/mobile" method="post">
<table>
<tr>
<td>手机号:</td>
<td><input type="text" name="mobile" value="13812349876"/></td>
<td></td>
</tr>
<tr>
<td>短信验证码:</td>
<td>
<input width="100" type="text" name="smsCode"/>
<a href="/verifycode/sms?mobile=13812349876">发送验证码</a>
</td>
<td></td>
</tr>
<tr>
<td>记住我</td>
<td><input type="checkbox" name="remember-me" value="true"/></td>
</tr>
<tr>
<td colspan="2" align="right"><button type="submit">登录</button></td>
</tr>
</table>
</form>
control打印:
Spring Security构建Rest服务-0801-短信验证码发送的更多相关文章
- php实现的IMEI限制的短信验证码发送类
php实现的IMEI限制的短信验证码发送类 <?php class Api_Sms{ const EXPIRE_SEC = 1800; // 过期时间间隔 const RESEND_SEC = ...
- PHP实现对短信验证码发送次数的限制(防机刷验证码)
PHP实现对短信验证码发送限制(防止机刷验证码) 对用户获取短信验证码的手机号.ip.和浏览器(使用唯一标识)进行限制.本文介绍的方法是对用户每天只能通过同一浏览器或同一ip地址获取验证码10次或者同 ...
- Spring Security构建Rest服务-1203-Spring Security OAuth开发APP认证框架之短信验证码登录
浏览器模式下验证码存储策略 浏览器模式下,生成的短信验证码或者图形验证码是存在session里的,用户接收到验证码后携带过来做校验. APP模式下验证码存储策略 在app场景下里是没有cookie信息 ...
- Spring Security构建Rest服务-0702-短信验证码登录
先来看下 Spring Security密码登录大概流程,模拟这个流程,开发短信登录流程 1,密码登录请求发送给过滤器 UsernamePasswordAuthenticationFilter 2,过 ...
- Spring Security构建Rest服务-1202-Spring Security OAuth开发APP认证框架之重构3种登录方式
SpringSecurityOAuth核心源码解析 蓝色表示接口,绿色表示类 1,TokenEndpoint 整个入口点,相当于一个controller,不同的授权模式获取token的地址都是 /oa ...
- Spring Security构建Rest服务-1201-Spring Security OAuth开发APP认证框架之实现服务提供商
实现服务提供商,就是要实现认证服务器.资源服务器. 现在做的都是app的东西,所以在app项目写代码 认证服务器: 新建 ImoocAuthenticationServerConfig 类,@Ena ...
- Spring Security构建Rest服务-1200-SpringSecurity OAuth开发APP认证框架
基于服务器Session的认证方式: 前边说的用户名密码登录.短信登录.第三方登录,都是普通的登录,是基于服务器Session保存用户信息的登录方式.登录信息都是存在服务器的session(服务器的一 ...
- Spring Security构建Rest服务-0800-Spring Security图片验证码
验证码逻辑 以前在项目中也做过验证码,生成验证码的代码网上有很多,也有一些第三方的jar包也可以生成漂亮的验证码.验证码逻辑很简单,就是在登录页放一个image标签,src指向一个controller ...
- Spring Security构建Rest服务-1100-单机Session管理
Session失效时间: springboot配置session失效时间,只需要在application.properties里配置 #session超时时间,低于60秒按60秒server.sess ...
随机推荐
- Shell获取当前路径
PRG="$0" while [ -h "$PRG" ]; do ls=`ls -ld "$PRG"` link=`expr "$ ...
- ArcGIS Desktop Python add-ins 插件类型
Python可以在ArcGIS 桌面程序中创建如下的插件类型: 插件类型 描述 按钮(button) 是一个简单功能定制形式,可以在点击情况下执行一些业务逻辑.它会执行一个或一系列的动作.按钮可以放在 ...
- SpringMVC上传图片总结(2)--- 使用百度webuploader上传组件进行上传图片
SpringMVC上传图片总结(2)--- 使用百度webuploader上传组件进行上传图片 在上一篇文章中,我们介绍了< SpringMVC上传图片的常规上传方法 >.本文接着第一 ...
- swagger 入门
官网:http://swagger.io/ Swagger UI 下载地址: https://github.com/swagger-api/swagger-ui 文档:README.md ### Do ...
- (KMP扩展 利用循环节来计算) Cyclic Nacklace -- hdu -- 3746
http://acm.hdu.edu.cn/showproblem.php?pid=3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others ...
- Java实现wc部分功能
GitHub仓库:https://github.com/TaoTaoLv1/WcProject 一.开发前PSP表格预估* PSP2.1 Personal Software Process Stage ...
- [Zend Mail]发送中文名附件出现乱码解决方案
Zend Framework 1.0.* “=?UTF-8?B?”.base64_encode($title).“?=” 发送中文名附件,结果如图: 英文名附件,结果截图: 解决办法就是将中文文件名拼 ...
- WPF 最简单的TextBox水印
最简单的TextBox加水印的方法,但是不具有很强的通用性. 如果你只是使用一次,或者用的不多,偷偷懒可以使用. 因为此方法只需要修改TextBox的Template,而不用重写何任代码. 注意: 1 ...
- Android中设置分割线
设置分隔线的方法一: 在需要设置分隔线的布局文件中加入如下代码: <View android:layout_width="fill_parent" andr ...
- 曲演杂坛--使用TRY CATCH应该注意的一个小细节
群里一个朋友遇到一个TRY CATCH的小问题,测试后发现是自己从来没有考虑的情况,写篇blog加深下印象 --============================================ ...