[转载]spring-security-oauth2(六) 短信验证码接口开发

本文详细介绍短信验证码接口的开发过程,包括生成、发送及图片验证码的处理,并通过策略模式进行重构,提升代码复用性和扩展性。

短信验证码接口开发

  1. 短信验证码生成接口
  2. 短信验证码发送接口
  3. 短信生成策略模板模式重构

1.短信验证码接口开发

1.1短信验证码生成接口

发送短信验证码controller


 
  1. package com.rui.tiger.auth.core.captcha;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.social.connect.web.HttpSessionSessionStrategy;
  5. import org.springframework.social.connect.web.SessionStrategy;
  6. import org.springframework.web.bind.ServletRequestBindingException;
  7. import org.springframework.web.bind.ServletRequestUtils;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.RestController;
  10. import org.springframework.web.context.request.ServletWebRequest;
  11. import javax.imageio.ImageIO;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import java.io.IOException;
  15. /**
  16. * 验证码控制器
  17. *
  18. * @author CaiRui
  19. * @date 2018-12-10 12:13
  20. */
  21. @RestController
  22. @Slf4j
  23. public class CaptchaController {
  24. public static final String CAPTCHA_SESSION_KEY = "captcha_session_key";
  25. private static final String FORMAT_NAME = "JPEG";
  26. @Autowired
  27. private CaptchaGenerate imageCaptchaGenerate;
  28. @Autowired
  29. private CaptchaGenerate smsCaptchaGenerate;
  30. @Autowired
  31. private SmsCaptchaSend smsCaptchaSend;
  32. //spring session 工具类
  33. private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
  34. /**
  35. * 获取图片验证码
  36. *
  37. * @param request
  38. * @param response
  39. * @throws IOException
  40. */
  41. @GetMapping( "/captcha/image")
  42. public void createKaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
  43. //1.接口生成验证码
  44. ImageCaptchaVo imageCaptcha = (ImageCaptchaVo) imageCaptchaGenerate.generate();
  45. //2.保存到session中
  46. sessionStrategy.setAttribute( new ServletWebRequest(request), CAPTCHA_SESSION_KEY, imageCaptcha);
  47. //3.写到响应流中
  48. response.setHeader( "Cache-Control", "no-store, no-cache"); // 没有缓存
  49. response.setContentType( "image/jpeg");
  50. ImageIO.write(imageCaptcha.getImage(), FORMAT_NAME, response.getOutputStream());
  51. }
  52. /**
  53. * 获取图片验证码
  54. *
  55. * @param request
  56. * @param response
  57. * @throws IOException
  58. */
  59. @GetMapping( "/captcha/sms")
  60. public void createSms(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletRequestBindingException {
  61. log.info( "获取短信验证码");
  62. //1.获取短信验证码
  63. CaptchaVo captchaVo = smsCaptchaGenerate.generate();
  64. //2.保存到session中
  65. sessionStrategy.setAttribute( new ServletWebRequest(request), CAPTCHA_SESSION_KEY + "sms", captchaVo);
  66. //3.发送
  67. String mobile = ServletRequestUtils.getRequiredStringParameter(request, "mobile");
  68. smsCaptchaSend.sendSms(mobile, captchaVo.getCode());
  69. }
  70. }

由于短信验证码和图片验证码基本结构都差不多,只是没有图形,故对实体进行调整


 
  1. package com.rui.tiger.auth.core.captcha;
  2. import lombok.Data;
  3. import java.awt.image.BufferedImage;
  4. import java.time.LocalDateTime;
  5. /**
  6. * 验证码
  7. *
  8. * @author CaiRui
  9. * @Date 2018/12/15 9:11
  10. */
  11. @Data
  12. public class CaptchaVo {
  13. /**
  14. * 验证码
  15. */
  16. private String code;
  17. /**
  18. * 失效时间 这个通常放在缓存中或维护在数据库中
  19. */
  20. private LocalDateTime expireTime;
  21. public CaptchaVo(String code, int expireAfterSeconds) {
  22. this.code = code;
  23. //多少秒后
  24. this.expireTime = LocalDateTime.now().plusSeconds(expireAfterSeconds);
  25. }
  26. public CaptchaVo(String code, LocalDateTime expireTime) {
  27. this.code = code;
  28. this.expireTime = expireTime;
  29. }
  30. /**
  31. * 是否失效
  32. *
  33. * @return
  34. */
  35. public boolean isExpried() {
  36. return LocalDateTime.now().isAfter(expireTime);
  37. }
  38. }

 
  1. package com.rui.tiger.auth.core.captcha;
  2. import lombok.Data;
  3. import java.awt.image.BufferedImage;
  4. import java.time.LocalDateTime;
  5. /**
  6. * 图片验证码信息对象
  7. *
  8. * @author CaiRui
  9. * @Date 2018/12/9 18:03
  10. */
  11. @Data
  12. public class ImageCaptchaVo extends CaptchaVo {
  13. /**
  14. * 图片验证码
  15. */
  16. private BufferedImage image;
  17. public ImageCaptchaVo(BufferedImage image, String code, int expireAfterSeconds) {
  18. super(code, expireAfterSeconds);
  19. this.image = image;
  20. }
  21. public ImageCaptchaVo(BufferedImage image, String code, LocalDateTime expireTime) {
  22. super(code, expireTime);
  23. this.image = image;
  24. }
  25. }

相关配置类调整修改


 
  1. package com.rui.tiger.auth.core.properties;
  2. /**
  3. * 短信验证码配置类
  4. * @author CaiRui
  5. * @Date 2018/12/15 9:30
  6. */
  7. public class SmsCaptchaProperties {
  8. /**
  9. * 长度
  10. */
  11. private int length= 6;
  12. /**
  13. * 过期秒数 默认3分钟
  14. */
  15. private int expireSeconds= 180;
  16. public int getLength() {
  17. return length;
  18. }
  19. public void setLength(int length) {
  20. this.length = length;
  21. }
  22. public int getExpireSeconds() {
  23. return expireSeconds;
  24. }
  25. public void setExpireSeconds(int expireSeconds) {
  26. this.expireSeconds = expireSeconds;
  27. }
  28. }

 
  1. package com.rui.tiger.auth.core.properties;
  2. /**
  3. * 验证码配置类
  4. * @author CaiRui
  5. * @Date 2018/12/15 9:43
  6. */
  7. public class CaptchaProperties {
  8. /**
  9. *图片验证码配置
  10. */
  11. private ImageCaptchaProperties image= new ImageCaptchaProperties();
  12. /**
  13. * 短信验证码配置
  14. */
  15. private SmsCaptchaProperties sms= new SmsCaptchaProperties();
  16. public ImageCaptchaProperties getImage() {
  17. return image;
  18. }
  19. public void setImage(ImageCaptchaProperties image) {
  20. this.image = image;
  21. }
  22. public SmsCaptchaProperties getSms() {
  23. return sms;
  24. }
  25. public void setSms(SmsCaptchaProperties sms) {
  26. this.sms = sms;
  27. }
  28. }

 
  1. package com.rui.tiger.auth.core.properties;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. /**
  4. * 权限配置文件父类(注意这里不用lombok 会读取不到)
  5. * 这里会有很多权限配置子模块
  6. *
  7. * @author CaiRui
  8. * @date 2018-12-6 8:41
  9. */
  10. @ConfigurationProperties(value = "tiger.auth", ignoreInvalidFields = true)
  11. public class SecurityProperties {
  12. /**
  13. * 浏览器配置类
  14. */
  15. private BrowserProperties browser = new BrowserProperties();
  16. /**
  17. * 验证码配置类
  18. */
  19. private CaptchaProperties captcha = new CaptchaProperties();
  20. public BrowserProperties getBrowser() {
  21. return browser;
  22. }
  23. public void setBrowser(BrowserProperties browser) {
  24. this.browser = browser;
  25. }
  26. public CaptchaProperties getCaptcha() {
  27. return captcha;
  28. }
  29. public void setCaptcha(CaptchaProperties captcha) {
  30. this.captcha = captcha;
  31. }
  32. }

短信验证码生成接口及实现类


 
  1. package com.rui.tiger.auth.core.captcha;
  2. /**
  3. * 验证码生成接口
  4. *
  5. * @author CaiRui
  6. * @date 2018-12-10 12:03
  7. */
  8. public interface CaptchaGenerate {
  9. /**
  10. * 生成验证码
  11. *
  12. * @return
  13. */
  14. CaptchaVo generate();
  15. }

 
  1. package com.rui.tiger.auth.core.captcha;
  2. import com.rui.tiger.auth.core.properties.SecurityProperties;
  3. import org.apache.commons.lang.RandomStringUtils;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * 短信验证码生成器
  8. *
  9. * @author CaiRui
  10. * @Date 2018/12/15 9:10
  11. */
  12. @Component( "smsCaptchaGenerate")
  13. public class SmsCaptchaGenerate implements CaptchaGenerate {
  14. @Autowired
  15. private SecurityProperties securityProperties;
  16. /**
  17. * 生成短信验证码
  18. *
  19. * @return
  20. */
  21. @Override
  22. public CaptchaVo generate() {
  23. String code = RandomStringUtils.randomNumeric(securityProperties.getCaptcha().getSms().getLength());
  24. return new CaptchaVo(code, securityProperties.getCaptcha().getSms().getExpireSeconds());
  25. }
  26. }

 

1.2短信登陆码发送接口

短信验证码发送接口及其实现类


 
  1. package com.rui.tiger.auth.core.captcha;
  2. /**
  3. * 短信验证码发送接口
  4. * @author CaiRui
  5. * @Date 2018/12/15 10:03
  6. */
  7. public interface SmsCaptchaSend {
  8. /**
  9. * 发送短信验证码
  10. * @param mobile
  11. * @param code
  12. * @return
  13. */
  14. boolean sendSms(String mobile,String code);
  15. }

 
  1. package com.rui.tiger.auth.core.captcha;
  2. import lombok.extern.slf4j.Slf4j;
  3. /**
  4. * @author CaiRui
  5. * @Date 2018/12/15 10:05
  6. */
  7. @Slf4j
  8. public class DefaultSmsCaptchaSender implements SmsCaptchaSend {
  9. //实际生产环境中,调用渠道供应商发送短信
  10. @Override
  11. public boolean sendSms(String mobile, String code) {
  12. log.info( "模拟向手机{}发送短信验证码{}",mobile,code);
  13. log.info( "短信渠道发送中...发送成功");
  14. return true;
  15. }
  16. }

验证码配置类


 
  1. package com.rui.tiger.auth.core.config;
  2. import com.google.code.kaptcha.Producer;
  3. import com.rui.tiger.auth.core.captcha.*;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
  6. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. /**
  10. * 验证码Bean生成配置类
  11. *
  12. * @author CaiRui
  13. * @date 2018-12-12 8:41
  14. */
  15. @Configuration
  16. public class CaptchaBeanConfig {
  17. //图片验证码生成
  18. @Bean
  19. // spring 容器中如果存在imageCaptchaGenerate的bean就不会再初始化该bean了
  20. //可参见:https://www.cnblogs.com/yixianyixian/p/7346894.html 这篇博文
  21. @ConditionalOnMissingBean(name = "imageCaptchaGenerate")
  22. public CaptchaGenerate imageCaptchaGenerate() {
  23. ImageCaptchaGenerate imageCaptchaGenerate = new ImageCaptchaGenerate();
  24. return imageCaptchaGenerate;
  25. }
  26. //短信验证码生成
  27. @Bean
  28. @ConditionalOnMissingBean(name = "smsCaptchaGenerate")
  29. public CaptchaGenerate smsCaptchaGenerate() {
  30. SmsCaptchaGenerate smsCaptchaGenerate = new SmsCaptchaGenerate();
  31. return smsCaptchaGenerate;
  32. }
  33. @Bean
  34. @ConditionalOnMissingBean(DefaultSmsCaptchaSender.class)
  35. public SmsCaptchaSend defaultSmsCaptchaSender() {
  36. DefaultSmsCaptchaSender defaultSmsCaptchaSender= new DefaultSmsCaptchaSender();
  37. return defaultSmsCaptchaSender;
  38. }
  39. }

在权限路径中放行 .antMatchers(securityProperties.getBrowser().getLoginPage(), "/authentication/require", "/captcha/*")


 
  1. package com.rui.tiger.auth.browser.config;
  2. import com.rui.tiger.auth.core.authentication.TigerAuthenticationFailureHandler;
  3. import com.rui.tiger.auth.core.authentication.TigerAuthenticationSuccessHandler;
  4. import com.rui.tiger.auth.core.captcha.CaptchaFilter;
  5. import com.rui.tiger.auth.core.properties.SecurityProperties;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  10. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  11. import org.springframework.security.core.userdetails.UserDetailsService;
  12. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  13. import org.springframework.security.crypto.password.PasswordEncoder;
  14. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  15. import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
  16. import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
  17. import javax.sql.DataSource;
  18. /**
  19. * 浏览器security配置类
  20. *
  21. * @author CaiRui
  22. * @date 2018-12-4 8:41
  23. */
  24. @Configuration
  25. public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
  26. @Autowired
  27. private SecurityProperties securityProperties;
  28. @Autowired
  29. private TigerAuthenticationFailureHandler tigerAuthenticationFailureHandler;
  30. @Autowired
  31. private TigerAuthenticationSuccessHandler tigerAuthenticationSuccessHandler;
  32. @Autowired
  33. private DataSource dataSource;
  34. @Autowired
  35. private UserDetailsService userDetailsService;
  36. /**
  37. * 密码加密解密
  38. *
  39. * @return
  40. */
  41. @Bean
  42. public PasswordEncoder passwordEncoder() {
  43. return new BCryptPasswordEncoder();
  44. }
  45. /**
  46. * 记住我持久化数据源
  47. * JdbcTokenRepositoryImpl CREATE_TABLE_SQL 建表语句可以先在数据库中执行
  48. *
  49. * @return
  50. */
  51. @Bean
  52. public PersistentTokenRepository persistentTokenRepository() {
  53. JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
  54. jdbcTokenRepository.setDataSource(dataSource);
  55. //第一次会执行CREATE_TABLE_SQL建表语句 后续会报错 可以关掉
  56. //jdbcTokenRepository.setCreateTableOnStartup(true);
  57. return jdbcTokenRepository;
  58. }
  59. @Override
  60. protected void configure(HttpSecurity http) throws Exception {
  61. //加入图片验证码过滤器
  62. CaptchaFilter captchaFilter = new CaptchaFilter();
  63. captchaFilter.setFailureHandler(tigerAuthenticationFailureHandler);
  64. captchaFilter.setSecurityProperties(securityProperties);
  65. captchaFilter.afterPropertiesSet();
  66. //图片验证码放在认证之前
  67. http.addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class)
  68. .formLogin()
  69. .loginPage( "/authentication/require") //自定义登录请求
  70. .loginProcessingUrl( "/authentication/form") //自定义登录表单请求
  71. .successHandler(tigerAuthenticationSuccessHandler)
  72. .failureHandler(tigerAuthenticationFailureHandler)
  73. .and()
  74. //记住我相关配置
  75. .rememberMe()
  76. .tokenRepository(persistentTokenRepository())
  77. .tokenValiditySeconds(securityProperties.getBrowser().getRemberMeSeconds())
  78. .userDetailsService(userDetailsService)
  79. .and()
  80. .authorizeRequests()
  81. .antMatchers(securityProperties.getBrowser().getLoginPage(),
  82. "/authentication/require", "/captcha/*") //此路径放行 否则会陷入死循环
  83. .permitAll()
  84. .anyRequest()
  85. .authenticated()
  86. .and()
  87. .csrf().disable() //跨域关闭
  88. ;
  89. }
  90. }

postman测试下

看控制台日志,可以看见我们的短信发送接口可以用

1.3 验证码生成策略模板方式重构

经过分析图片验证码和手机验证码的创建流程基本都是一样,主要经过三步。

  1. 生成验证码
  2. 保存到session中
  3. 发送(图片响应流写回,短信调用渠道直接发送)

下面结合UML图和代码看看是怎么实现的吧。

CaptchaController调用CaptchaCreateService,CaptchaCreateService策略调用CaptchaProcessor

CaptchaController 经过调整后如下,将原来的分别生成图片和短信的合并调整


 
  1. package com.rui.tiger.auth.core.captcha;
  2. import com.rui.tiger.auth.core.captcha.sms.SmsCaptchaSend;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.social.connect.web.HttpSessionSessionStrategy;
  6. import org.springframework.social.connect.web.SessionStrategy;
  7. import org.springframework.web.bind.ServletRequestBindingException;
  8. import org.springframework.web.bind.ServletRequestUtils;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.PathVariable;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import org.springframework.web.context.request.ServletWebRequest;
  13. import javax.imageio.ImageIO;
  14. import javax.servlet.http.HttpServletRequest;
  15. import javax.servlet.http.HttpServletResponse;
  16. import java.io.IOException;
  17. /**
  18. * 验证码控制器
  19. *
  20. * @author CaiRui
  21. * @date 2018-12-10 12:13
  22. */
  23. @RestController
  24. @Slf4j
  25. public class CaptchaController {
  26. @Autowired
  27. private CaptchaCreateService captchaCreateService;
  28. /**
  29. * 获取验证码
  30. *
  31. * @param request
  32. * @param response
  33. * @throws IOException
  34. */
  35. @GetMapping( "/captcha/{type}")
  36. public void createCaptcha(HttpServletRequest request, HttpServletResponse response, @PathVariable String type) throws Exception {
  37. log.info( "获取验证码开始");
  38. captchaCreateService.createCaptcha( new ServletWebRequest(request, response), type);
  39. log.info( "获取验证码结束");
  40. }
  41. }

验证码生成接口


 
  1. package com.rui.tiger.auth.core.captcha;
  2. import org.springframework.web.context.request.ServletWebRequest;
  3. /**
  4. * @author CaiRui
  5. * @Date 2018/12/15 21:27
  6. */
  7. public interface CaptchaCreateService {
  8. /**
  9. * 生成验证码
  10. * @param request
  11. * @param type
  12. */
  13. void createCaptcha(ServletWebRequest request, String type);
  14. }

 
  1. package com.rui.tiger.auth.core.captcha;
  2. import com.rui.tiger.auth.core.support.strategy.StrategyContainerImpl;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.stereotype.Service;
  5. import org.springframework.web.context.request.ServletWebRequest;
  6. /**
  7. * @author CaiRui
  8. * @Date 2018/12/15 21:27
  9. */
  10. @Service
  11. @Slf4j
  12. public class CaptchaCreateServiceImpl implements CaptchaCreateService {
  13. /**
  14. * 生成验证码
  15. *
  16. * @param request
  17. * @param type
  18. */
  19. @Override
  20. public void createCaptcha(ServletWebRequest request, String type) {
  21. CaptchaTypeEnum captchaType=CaptchaTypeEnum.forCode(type);
  22. if (type== null){
  23. throw new CaptchaException( "验证码类型不支持");
  24. }
  25. try {
  26. StrategyContainerImpl.getStrategy(CaptchaProcessor.class,captchaType)
  27. .create(request);
  28. } catch (Exception e) {
  29. log.info( "");
  30. }
  31. }
  32. }

验证码类型枚举类


 
  1. package com.rui.tiger.auth.core.captcha;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. /**
  5. * 验证码类型枚举类
  6. * @author CaiRui
  7. * @Date 2018/12/15 17:58
  8. */
  9. public enum CaptchaTypeEnum {
  10. SMS( "sms", "短信"),
  11. IMAGE( "image", "图形验证码");
  12. CaptchaTypeEnum(String code, String desc) {
  13. this.code = code;
  14. this.desc = desc;
  15. }
  16. private static Map<String,CaptchaTypeEnum> codeLookup = new HashMap<String,CaptchaTypeEnum>();
  17. private String code;
  18. private String desc;
  19. static {
  20. for (CaptchaTypeEnum type : CaptchaTypeEnum.values()) {
  21. codeLookup.put(type.code, type);
  22. }
  23. }
  24. /**
  25. * 根据类型获取枚举类
  26. * @param code
  27. * @return
  28. */
  29. public static CaptchaTypeEnum forCode(String code) {
  30. return codeLookup.get(code);
  31. }
  32. public String getCode() {
  33. return code;
  34. }
  35. }

验证码生成策略接口,


 
  1. package com.rui.tiger.auth.core.captcha;
  2. import com.rui.tiger.auth.core.support.strategy.IStrategy;
  3. import org.springframework.web.context.request.ServletWebRequest;
  4. /**
  5. * 验证码处理器接口
  6. * @author CaiRui
  7. * @Date 2018/12/15 17:53
  8. */
  9. public interface CaptchaProcessor extends IStrategy<CaptchaTypeEnum> {
  10. /**
  11. * 验证码
  12. */
  13. String CAPTCHA_SESSION_KEY= "captcha_session_key_";
  14. /**
  15. * 创建验证码
  16. * @param request 封装请求和响应
  17. * @throws Exception
  18. */
  19. void create(ServletWebRequest request) throws Exception;
  20. }

抽象实现父类


 
  1. package com.rui.tiger.auth.core.captcha;
  2. import org.apache.commons.lang.StringUtils;
  3. import org.springframework.social.connect.web.HttpSessionSessionStrategy;
  4. import org.springframework.social.connect.web.SessionStrategy;
  5. import org.springframework.web.bind.ServletRequestBindingException;
  6. import org.springframework.web.context.request.ServletWebRequest;
  7. import java.io.IOException;
  8. /**
  9. * 验证码处理器抽象父类
  10. * @author CaiRui
  11. * @Date 2018/12/15 18:21
  12. */
  13. public abstract class AbstractCaptchaProcessor<C extends CaptchaVo> implements CaptchaProcessor {
  14. private SessionStrategy sessionStrategy= new HttpSessionSessionStrategy();
  15. /**
  16. * 创建验证码
  17. *
  18. * @param request 封装请求和响应
  19. * @throws Exception
  20. */
  21. @Override
  22. public void create(ServletWebRequest request) throws Exception {
  23. //生成
  24. C captcha=generateCaptcha(request);
  25. //保存
  26. save(request,captcha);
  27. //发送
  28. send(request,captcha);
  29. }
  30. protected abstract C generateCaptcha(ServletWebRequest request);
  31. protected abstract void send(ServletWebRequest request, C captcha) throws IOException, ServletRequestBindingException;
  32. private void save(ServletWebRequest request, C captcha) {
  33. sessionStrategy.setAttribute(request, CAPTCHA_SESSION_KEY+getCaptchaTypeFromUrl(request), captcha);
  34. }
  35. /**
  36. * 根据请求的url获取校验码的类型
  37. * @param request
  38. * @return
  39. */
  40. private String getCaptchaTypeFromUrl(ServletWebRequest request) {
  41. return StringUtils.substringAfter(request.getRequest().getRequestURI(), "/captcha/");
  42. }
  43. }

图片验证码生成实现


 
  1. package com.rui.tiger.auth.core.captcha.image;
  2. import com.rui.tiger.auth.core.captcha.AbstractCaptchaProcessor;
  3. import com.rui.tiger.auth.core.captcha.CaptchaGenerate;
  4. import com.rui.tiger.auth.core.captcha.CaptchaTypeEnum;
  5. import com.rui.tiger.auth.core.captcha.ImageCaptchaVo;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9. import org.springframework.web.context.request.ServletWebRequest;
  10. import javax.imageio.ImageIO;
  11. import javax.servlet.http.HttpServletResponse;
  12. import java.io.IOException;
  13. /**
  14. * @author CaiRui
  15. * @Date 2018/12/15 18:31
  16. */
  17. @Service
  18. @Slf4j
  19. public class ImageCaptchaProcessor extends AbstractCaptchaProcessor<ImageCaptchaVo> {
  20. private static final String FORMAT_NAME = "JPEG";
  21. @Autowired
  22. private CaptchaGenerate imageCaptchaGenerate;
  23. /**
  24. * 获得策略条件
  25. *
  26. * @return 用来注册的策略处理条件
  27. */
  28. @Override
  29. public CaptchaTypeEnum getCondition() {
  30. return CaptchaTypeEnum.IMAGE;
  31. }
  32. @Override
  33. protected ImageCaptchaVo generateCaptcha(ServletWebRequest request) {
  34. return (ImageCaptchaVo) imageCaptchaGenerate.generate();
  35. }
  36. @Override
  37. protected void send(ServletWebRequest request, ImageCaptchaVo captcha) throws IOException {
  38. HttpServletResponse response=request.getResponse();
  39. response.setHeader( "Cache-Control", "no-store, no-cache"); // 没有缓存
  40. response.setContentType( "image/jpeg");
  41. ImageIO.write(captcha.getImage(), FORMAT_NAME, response.getOutputStream());
  42. }
  43. }

短信验证码生成实现


 
  1. package com.rui.tiger.auth.core.captcha.sms;
  2. import com.rui.tiger.auth.core.captcha.AbstractCaptchaProcessor;
  3. import com.rui.tiger.auth.core.captcha.CaptchaGenerate;
  4. import com.rui.tiger.auth.core.captcha.CaptchaTypeEnum;
  5. import com.rui.tiger.auth.core.captcha.CaptchaVo;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9. import org.springframework.web.bind.ServletRequestBindingException;
  10. import org.springframework.web.bind.ServletRequestUtils;
  11. import org.springframework.web.context.request.ServletWebRequest;
  12. /**
  13. * @author CaiRui
  14. * @Date 2018/12/15 18:29
  15. */
  16. @Service
  17. @Slf4j
  18. public class SmsCaptchaProcessor extends AbstractCaptchaProcessor<CaptchaVo> {
  19. @Autowired
  20. private CaptchaGenerate smsCaptchaGenerate;
  21. @Autowired
  22. private SmsCaptchaSend captchaSend;
  23. /**
  24. * 获得策略条件
  25. *
  26. * @return 用来注册的策略处理条件
  27. */
  28. @Override
  29. public CaptchaTypeEnum getCondition() {
  30. return CaptchaTypeEnum.SMS;
  31. }
  32. @Override
  33. protected CaptchaVo generateCaptcha(ServletWebRequest request) {
  34. return smsCaptchaGenerate.generate();
  35. }
  36. @Override
  37. protected void send(ServletWebRequest request, CaptchaVo captcha) throws ServletRequestBindingException {
  38. String mobile= ServletRequestUtils.getRequiredStringParameter(request.getRequest(), "mobile");
  39. captchaSend.sendSms(mobile, captcha.getCode());
  40. }
  41. }

ok  重构完成 下面我们自定义短信登陆开发

个人码云地址:https://gitee.com/krui/tiger-auth 

文章转载至:https://blog.youkuaiyun.com/ahcr1026212/article/details/85001933

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值