欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring与jcaptcha集成

程序员文章站 2022-03-15 14:54:37
...

需求:

验证码非常常见,那么在spring中使用jcaptcha进行认证那么需要集成

实现:

mvn:

<!-- code check captcha start -->
<dependency>
	<groupId>com.octo.captcha</groupId>
	<artifactId>jcaptcha</artifactId>
	<version>1.0</version>
</dependency>
<!-- code check captcha end -->

一般仓库中没有对应的jar,比如imaging-01012005.jar那么需要手动添加仓库

<repository>
	<id>atlassian</id>
	<name>atlassian</name>
	<url>http://maven.jahia.org/maven2</url>
	<releases>
		<enabled>true</enabled>
	</releases>
	<snapshots>
		<enabled>false</enabled>
	</snapshots>
</repository>

基于注解mvc,那么图片的请求路径为Controller,流程为请求path:/anon/getcode产生验证码

这样spring的配置信息为:

<context:component-scan base-package="com.someabcd.csr" />
<!-- check code start -->
<bean id="captchaService"
	class="com.octo.captcha.service.multitype.GenericManageableCaptchaService">
	<description>验证码服务</description>
	<constructor-arg index="0">
		<ref bean="com.someabcd.csr.web.crsCaptchaEngine" />
	</constructor-arg>
	<constructor-arg index="1">
		<value>300</value>
	</constructor-arg><!--超时时间 秒 -->
	<constructor-arg index="2">
		<value>20000</value>
	</constructor-arg><!--最大并发数 -->
	<constructor-arg index="3">
		<value>20000</value>
	</constructor-arg>
</bean>

com.someabcd.csr.web.crsCaptchaEngine类为:

@Component("com.someabcd.csr.web.crsCaptchaEngine")
public class CSRCaptchaEngine extends ListImageCaptchaEngine {

	@Override
	protected void buildInitialFactories() {
		int minWordLength = 4;
		int maxWordLength = 5;
		int fontSize = 50;
		int imageWidth = 152;
		int imageHeight = 100;
		WordGenerator wordGenerator = new RandomWordGenerator(
				"0123456789abcdefghijklmnopqrstuvwxyz");
		TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength,
				maxWordLength, new RandomListColorGenerator(new Color[] {
						new Color(23, 170, 27), new Color(220, 34, 11),
						new Color(23, 67, 172) }), new TextDecorator[] {});
		BackgroundGenerator background = new UniColorBackgroundGenerator(
				imageWidth, imageHeight, Color.white);
		FontGenerator font = new RandomFontGenerator(fontSize, fontSize,
				new Font[] { new Font("nyala", Font.BOLD, fontSize),
						new Font("Bell MT", Font.PLAIN, fontSize),
						new Font("Credit valley", Font.BOLD, fontSize) });

		ImageDeformation postDef = new ImageDeformationByFilters(
				new ImageFilter[] {});
		ImageDeformation backDef = new ImageDeformationByFilters(
				new ImageFilter[] {});
		ImageDeformation textDef = new ImageDeformationByFilters(
				new ImageFilter[] {});

		WordToImage word2image = new DeformedComposedWordToImage(font,
				background, randomPaster, backDef, textDef, postDef);
		addFactory(new GimpyFactory(wordGenerator, word2image));
	}
}

处理请求的Controller:

@Controller
@RequestMapping("anon")
public class AnonController {

	@Autowired
	private GenericManageableCaptchaService captchaService;

	@RequestMapping(value = "/getcode", method = RequestMethod.GET)
	public void getCode(HttpServletRequest httpServletRequest,
			HttpServletResponse httpServletResponse) {

		byte[] captchaChallengeAsJpeg = null;
		// 输出jpg的字节流
		ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
		try {
			String captchaId = httpServletRequest.getSession().getId();
			BufferedImage challenge = (BufferedImage) captchaService
					.getChallengeForID(captchaId,
							httpServletRequest.getLocale());

			// a jpeg encoder
			JPEGImageEncoder jpegEncoder = JPEGCodec
					.createJPEGEncoder(jpegOutputStream);
			jpegEncoder.encode(challenge);
			captchaChallengeAsJpeg = jpegOutputStream.toByteArray();

			// flush it in the response
			httpServletResponse.setHeader("Cache-Control", "no-store");
			httpServletResponse.setHeader("Pragma", "no-cache");
			httpServletResponse.setDateHeader("Expires", 0);
			httpServletResponse.setContentType("image/jpeg");
			ServletOutputStream responseOutputStream = httpServletResponse
					.getOutputStream();
			responseOutputStream.write(captchaChallengeAsJpeg);
			responseOutputStream.flush();
			responseOutputStream.close();
		} catch (Exception e) {
			try {
				httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			return;
		}

	}
}

验证码的显示:

<tr>
	<td colspan="2" align="center">
		<img 
				src="${basePath}anon/getcode"
				onclick="this.src='${basePath}anon/getcode?d='+new Date()*1" width="160" height="30"/>
	</td>
</tr>
<tr>
	<td height="40" align="right">
		<strong>
			验证码:
		</strong>
	</td>
	<td>
		<input name="code" type="text" id="code" vld="{required:true}" class="input"/>
	</td>
</tr>

验证码验证代码块:

Boolean isCorrect = Boolean.FALSE;
String captchaId = request.getSession().getId();
String code = request.getParameter("code");
try {
	isCorrect = captchaService.validateResponseForID(captchaId,
			code);
	if (!isCorrect) {
		log.info("check code error!");
		return "usr/tologin";
	}
} catch (Exception e) {
	log.error(e.getMessage());
}

     

备注:

可以把CaptchaEngine也配置的配置文件中,好处是可以随时修改,缺点是20%的事情缺耗费了80%时间,且这20%不重要