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 ...
随机推荐
- IntellJ IDEA javax.servlet.ServletException 找不到javax.servlet.ServletException的类 java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
误状态:错误显示 解决: (1)说明缺少包---->添加如下包配置 <dependency> <groupId>javax.servlet.jsp</groupId ...
- HDU 2546 饭卡 (01背包问题)
题意:中文的吧,飘过~ 析:学过DP的都应该感觉到是动态规划吧,就是一个01背包问题,不同的是,这个题又加入一些新的条件,就是不满5元不能消费,过了5元即使超了也行(这个学校真不错,都可以预支),最后 ...
- 笔记本的Windows系统怎么设置有了外接鼠标后停用触摸板
点击控制面板,切换小图标模式,找到鼠标,点击它,然后会弹出一个窗口,找到ELAN选项卡(一般有个红色图标,不过可能需要对应驱动才会有此选项卡),选中插入外置 USB 指向装置时禁用.点击确定保存配置即 ...
- 批处理(bat)的注释方法
前面两个批处理教程的转贴,写得实在是太好了,内容详实,语言风趣,举例清晰.说实话,原作者幽默的文风用来写 批处理教程,而不是写文学小说,实在是有些屈才,但这样优秀的教程,用在枯燥乏味的程序事业里,确实 ...
- day3之文件操作
一,文件操作基本流程. # 1.打开文件,产生文件句柄 # 2.操作文件句柄 # 3.关闭文件句柄 # f1 = open('11.txt',encoding='utf-8', mode='r') # ...
- HDU6205 Coprime Sequence 2017-05-07 18:56 36人阅读 评论(0) 收藏
Coprime Sequence Time Limit: 2000/1000 MS (Ja ...
- HDU1253 胜利大逃亡(BFS) 2016-07-24 13:41 67人阅读 评论(0) 收藏
胜利大逃亡 Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示 ...
- (原创)PetaPoco使用小记(2014-5-5更新)
接触PetaPoco已经有一段时间了,为了全面了解一下PetaPoco,刚好结合目前在做的一个项目,对常用的几个业务操作用PetaPoco进行改写,如增删改查.分页以及存储过程的调用,在文章的最后附上 ...
- 万恶的KPI、新兴的OKR及让人纠结的程序员考核
最近两天在研究研发部门如何进行绩效管理(其实一直都在思考,关注,实践,总感觉无从下手,也想求助咨询公司,无奈囊中羞涩).查了两天的资料,主要的方向是KPI,OKR,谷歌等互联网公司的考核方法.这里做个 ...
- C#实现在图片上动态写内容
之前在项目上遇到这么一个需求,就是要在图片上写内容,而且要求是动态,我所谓的动态就是在图片上写的内容是动态的.网上找了找,很多人实现了网图片上写内容的功能,但是,并没有实现动态.所以在这里把我的解决办 ...