6. Spring Boot + Spring Security 短信发送功能(发送)

**采用了抽象的公共配置的方法
ValidateCodeController:前后跳转控制器
ValidateCodeProcessor: 验证码的具体逻辑接口
AbstractValidateCodeProcessor: 抽象类实现验证码的具体逻辑
ImageCodeProcessor: 图片验证码具体逻辑实现
SmsCodeProcessor: 短信验证码具体逻辑实现
ValidateCodeGenerator: 验证码生成接口
SmsCodeGenerator: 短信验证码生成类
ImageCodeGenerator:图片验证码生成类
**
在这里插入图片描述

  1. 项目目录
    在这里插入图片描述
  2. ImageCode.java 图片属性类

    package com.imooc.security.core.validate.code.image;
    
    import java.awt.image.BufferedImage;
    import java.time.LocalDateTime;
    
    import com.imooc.security.core.validate.code.ValidateCode;
    /**
     * 图片验证码
     * @author cjj
     * @date 2018年10月8日
     * @email 729165621@qq.com
     * @blog blog.csdn.net/qq_29451823
     */
    public class ImageCode extends ValidateCode{
    	
    	//图片
    	private BufferedImage image;
    	
    
    	public ImageCode(BufferedImage image, String code, int expireTime) {
    		super(code,expireTime);
    		this.image = image;
    	}
    	
    	public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) {
    		super(code,expireTime);
    		this.image = image;
    	}
    	
    	public BufferedImage getImage() {
    		return image;
    	}
    	public void setImage(BufferedImage image) {
    		this.image = image;
    	}
    	
    }
  1. ValidateCode.java 短信属性类(因为短信类的部分属性与图片类一样,并且比图片类多)
package com.imooc.security.core.validate.code;
import java.time.LocalDateTime;
/**
 * 短信验证码
 * @author cjj
 * @date 2018年10月8日
 * @email 729165621@qq.com
 * @blog blog.csdn.net/qq_29451823
 */
public class ValidateCode {
	
	//随机数
	private  String code;
	//过期时间
	private LocalDateTime expireTime;
	
	public ValidateCode() {
		super();
	}
	
	public ValidateCode( String code, int expireTime) {
		super();
		this.code = code;
		this.expireTime = LocalDateTime.now().plusSeconds(expireTime);//生成一个过期的时间点
	}
	
	public ValidateCode(String code, LocalDateTime expireTime) {
		super();
		this.code = code;
		this.expireTime = 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;
	}

	public boolean isExpried() {
		return LocalDateTime.now().isAfter(expireTime);//判断当前时间是否在过期时间之后
	}
	
	
}

  1. ValidateCodeGenerator.java验证码自动生成接口
package com.imooc.security.core.validate.code;
import org.springframework.web.context.request.ServletWebRequest;

public interface ValidateCodeGenerator {
	
	ValidateCode createImage(ServletWebRequest request);
	
}

  1. 、ImageCodeGenertor.java 图片验证码生成实现类
package com.imooc.security.core.validate.code.image;

import java.awt.Color;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

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;
import com.imooc.security.core.validate.code.ValidateCodeGenerator;

@Component("imageCodeGenertor")
public class ImageCodeGenertor implements ValidateCodeGenerator{
	
	@Autowired
	private SecurityProperties securityProperties;

	 public ImageCode createImage(ServletWebRequest request) {
			
		 //获取用户设置的宽度
		int width = ServletRequestUtils.getIntParameter(request.getRequest(), "width",
				securityProperties.getValidate().getImage().getWidth());
		//获取用户设置的高度
		int height = ServletRequestUtils.getIntParameter(request.getRequest(), "height",
				securityProperties.getValidate().getImage().getHeight());

		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		Graphics g = image.getGraphics();

		Random random = new Random();

		g.setColor(getRandColor(200, 250));
		g.fillRect(0, 0, width, height);
		g.setFont(new Font("Times New Roman", Font.ITALIC, 20));
		g.setColor(getRandColor(160, 200));
		for (int i = 0; i < 155; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int xl = random.nextInt(12);
			int yl = random.nextInt(12);
			g.drawLine(x, y, x + xl, y + yl);
		}

		String sRand = "";
		//生成随机数
		for (int i = 0; i < securityProperties.getValidate().getImage().getLength(); i++) {
			String rand = String.valueOf(random.nextInt(10));
			sRand += rand;
			g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
			g.drawString(rand, 13 * i + 6, 16);
		}

		g.dispose();

		return new ImageCode(image, sRand, securityProperties.getValidate().getImage().getExprieIn());

	}
	/**
	 * 生成的随机条纹码
	 * @param fc
	 * @param bc
	 * @return
	 */
	private Color getRandColor(int fc, int bc) {
		Random random = new Random();
		if (fc > 255) {
			fc = 255;
		}
		if (bc > 255) {
			bc = 255;
		}
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);

	}

	public SecurityProperties getSecurityProperties() {
		return securityProperties;
	}

	public void setSecurityProperties(SecurityProperties securityProperties) {
		this.securityProperties = securityProperties;
	}
	
	
}

  1. SmsCodeGenertor.java 短信验证码生成代码
package com.imooc.security.core.validate.code.sms;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

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;
import com.imooc.security.core.validate.code.ValidateCode;
import com.imooc.security.core.validate.code.ValidateCodeGenerator;
			   
@Component("smsCodeGenertor")
public class SmsCodeGenertor implements ValidateCodeGenerator{
	
	@Autowired
	private SecurityProperties securityProperties;

	 public ValidateCode createImage(ServletWebRequest request) {
		String code = RandomStringUtils.randomNumeric(securityProperties.getValidate().getSms().getLength());
		return new ValidateCode(code, securityProperties.getValidate().getSms().getExprieIn());
	}


	public SecurityProperties getSecurityProperties() {
		return securityProperties;
	}

	public void setSecurityProperties(SecurityProperties securityProperties) {
		this.securityProperties = securityProperties;
	}
	
	
}

  1. ValidateCodeProcessor.java验证码业务逻辑接口,验证码处理逻辑,都是分3步,第一步创建生成,第二步骤保存,第三步骤发送。所有所有不同的验证码只有发送的实现是不一样的,可以由具体的验证码子类实现。
package com.imooc.security.core.validate.code;

import org.springframework.web.context.request.ServletWebRequest;

/**
 * 效验码处理器,封装不同效验码的处理逻辑
 * @author cjj
 * @date 2018年11月5日
 * @email 729165621@qq.com
 * @blog blog.csdn.net/qq_29451823
 */
public interface ValidateCodeProcessor {
	
	/**
	 * 验证码放入session时的前缀
	 */
	String SESSION_KEY_PREFIX = "SESSION_KEY_FOR_CODE_";
	
	/**
	 * 创建效验码
	 * ServletWebRequest servlet的封装类,request何response都可以放在这里面
	 * @param request
	 * @throws Exception
	 */
	void create(ServletWebRequest request) throws Exception;
}

  1. AbstractValidateCodeProcesser.java 验证码处理逻辑抽象实现类
package com.imooc.security.core.validate.code.impl;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
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.context.request.ServletWebRequest;

import com.imooc.security.core.validate.code.ValidateCode;
import com.imooc.security.core.validate.code.ValidateCodeGenerator;
import com.imooc.security.core.validate.code.ValidateCodeProcessor;

public abstract class AbstractValidateCodeProcesser<C extends ValidateCode> implements ValidateCodeProcessor{
	
	/**
	 * 操作session的工具类
	 */ 
	private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
	/**
	 * 收集系统中所有的{@link ValidateCodeGenerator} 接口的实现
	 *
	 */
	@Autowired
	private Map<String,ValidateCodeGenerator> validateCodeGenerators;
	
	
	public void create(ServletWebRequest request) throws Exception {
		C validateCode =  generate(request);//创建
		save(request,validateCode);//保存
		send(request,validateCode);//发送
	}
	
	/**
	 * 生成校验码
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private  C generate(ServletWebRequest request) {
		String type = getProcessOrType(request).trim();
		//spring常见的依赖搜索,定向的去搜索某一个接口具体的实现							  
		ValidateCodeGenerator validateCodeGenerator = validateCodeGenerators.get(type+"CodeGenertor");
		C c = (C)validateCodeGenerator.createImage(request);
		return c;
	}
	/**
	 * 发送效验码,由子类实现
	 * @param request
	 * @param validateCode
	 * @throws Exception 
	 */
	protected  abstract void send(ServletWebRequest request, C validateCode) throws Exception;

	/**
	 * 保存效验码
	 * @param request
	 * @param validateCode
	 */
	private void save(ServletWebRequest request, C validateCode) {
		sessionStrategy.setAttribute(request, SESSION_KEY_PREFIX + getProcessOrType(request).toUpperCase(), validateCode);
	}
	
	/**
	 * 根据请求的URL获取校验的类型
	 * @param request
	 * @return
	 */
	private String getProcessOrType(ServletWebRequest request) {
		//从第一次出现该字符的位置往后面截取
		return StringUtils.substringAfter(request.getRequest().getRequestURI(), "/code/");
	}

	
	
}


  1. ImageCodeProcessor.java 图片验证码具体的发送逻辑
package com.imooc.security.core.validate.code.image;

import java.io.IOException;

import javax.imageio.ImageIO;

import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;

import com.imooc.security.core.validate.code.impl.AbstractValidateCodeProcesser;

@Component("imageCodeProcessor")
public class ImageCodeProcessor extends AbstractValidateCodeProcesser<ImageCode>{
		
	protected void send(ServletWebRequest request, ImageCode imageCode) throws IOException {
	//图片验证码IO输出流就可以了
		ImageIO.write(imageCode.getImage(), "JPEG", request.getResponse().getOutputStream());
	}
}

  1. SmsCodeProcessor.java 短信验证码是由所使用的短信平台接口发送的,所有这里就模拟发送即可。
package com.imooc.security.core.validate.code.sms;

import javax.servlet.ServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;

import com.imooc.security.core.validate.code.ValidateCode;
import com.imooc.security.core.validate.code.impl.AbstractValidateCodeProcesser;

@Component("smsCodeProcessor")
public class SmsCodeProcessor extends AbstractValidateCodeProcesser<ValidateCode>{
	/**
	 * 短信发送器
	 */
	@Autowired
	private SmsCodeSender smsCodeSender;
	
	protected  void send(ServletWebRequest request, ValidateCode validateCode) throws ServletRequestBindingException {
		String mobile = ServletRequestUtils.getRequiredStringParameter(request.getRequest(), "mobile");
		smsCodeSender.send(mobile, validateCode.getCode());
	};
	
}

/*具体的发送,手动模拟*/
package com.imooc.security.core.validate.code.sms;

public interface SmsCodeSender {

	void send (String mobile, String code);
}



package com.imooc.security.core.validate.code.sms;

public class DefaultSmsCodeSender implements SmsCodeSender {

	@Override
	public void send(String mobile, String code) {
		System.out.println("像手机"+mobile+"发送 选项验证码"+code);
	}

}


  1. ValidateCodeBeanConfig.java 使用@Configuration配置生成Bean,并且可以验证其他注解的Bean
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.image.ImageCodeGenertor;
import com.imooc.security.core.validate.code.sms.DefaultSmsCodeSender;
import com.imooc.security.core.validate.code.sms.SmsCodeSender;

@Configuration
public class ValidateCodeBeanConfig {
	
	@Autowired
	private SecurityProperties securityProperties;
	
	@Bean							
	@ConditionalOnMissingBean(name="imageCodeGenertor")//如果初始化spring容器的时候,里面有imageCodeGenerator则就不用加载下面的内容
	public ValidateCodeGenerator imageCodeGenertor() {
		ImageCodeGenertor codeGenertor = new ImageCodeGenertor();
		codeGenertor.setSecurityProperties(securityProperties);
		return codeGenertor;
	}
	
	@Bean
	@ConditionalOnMissingBean(SmsCodeSender.class)
	public SmsCodeSender smsCodeSender() {
		return new DefaultSmsCodeSender();
	}
}

  1. BrowserSecurityConfig.java 安全框架配置,只需要添加验证码访问路径就行了
			.and()
			.authorizeRequests()//对请求做一个授权
			.antMatchers("/authentication/require"
					,securityProperties.getBrowser().getLoginPage()
					,"/code/*").permitAll()//访问这个页面的时候不需要授权
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 是一个用于构建微服务的开源框架,它能够快速搭建项目并且提供了许多便捷的功能和特性。Spring Security 是一个用于处理认证和授权的框架,可以保护我们的应用程序免受恶意攻击。JWT(JSON Web Token)是一种用于身份验证的开放标准,可以被用于安全地传输信息。Spring MVC 是一个用于构建 Web 应用程序的框架,它能够处理 HTTP 请求和响应。MyBatis 是一个用于操作数据库的框架,可以简化数据库操作和提高效率。Redis 是一种高性能的键值存储系统,可以用于缓存与数据存储。 基于这些技术,可以搭建一个商城项目。Spring Boot 可以用于构建商城项目的后端服务,Spring Security 可以确保用户信息的安全性,JWT 可以用于用户的身份验证,Spring MVC 可以处理前端请求,MyBatis 可以操作数据库,Redis 可以用于缓存用户信息和商品信息。 商城项目的后端可以使用 Spring BootSpring Security 来搭建,通过 JWT 来处理用户的身份验证和授权。数据库操作可以使用 MyBatis 来简化与提高效率,同时可以利用 Redis 来缓存一些常用的数据和信息,提升系统的性能。前端请求则可以通过 Spring MVC 来处理,实现商城项目的整体功能。 综上所述,借助于 Spring BootSpring Security、JWT、Spring MVC、MyBatis 和 Redis 这些技术,可以构建出一个高性能、安全可靠的商城项目,为用户提供良好的购物体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值