この認証コードの実装は多くのプラグインを使用せず、コードを直接提示します。すぐに使用できます。
1.認証コードクラス
package com.example.security.util.captcha;
import lombok.Data;
/**
* 認証コードクラス
*/
@Data
public class CaptchaCode {
private String code;
private byte[] imageBytes;
private long expirationTime;
}
2.認証コード生成インターフェース
package com.example.security.util.captcha;
import java.io.IOException;
import java.io.OutputStream;
/**
* 認証コード生成インターフェース
*/
public interface CaptchaGenerator {
/**
* 認証コードを生成し、画像をosに書き込む
*
* @param width 幅
* @param height 高さ
* @param os 出力ストリーム
* @return 生成されたコード
* @throws IOException 入出力例外
*/
String generate(int width, int height, OutputStream os) throws IOException;
/**
* 認証コードオブジェクトを生成する
*
* @param width 幅
* @param height 高さ
* @return 認証コードオブジェクト
* @throws IOException 入出力例外
*/
CaptchaCode generate(int width, int height) throws IOException;
}
3.認証コード生成実装クラス
package com.example.security.util.captcha;
import com.example.common.RandomHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
/**
* 単純な文字認証コード生成実装クラス
*/
public class SimpleTextCaptchaGenerator implements CaptchaGenerator {
private static final Logger logger = LoggerFactory.getLogger(SimpleTextCaptchaGenerator.class);
private static final String[] FONT_FAMILIES = {"メイリオ", "游ゴシック", "ヒラギノ角ゴ", "sans-serif", "serif"};
private static final int CODE_LENGTH = 4;
/**
* 背景の色とサイズ、妨害線を設定する
*
* @param graphics グラフィックスオブジェクト
* @param width 幅
* @param height 高さ
*/
private static void configureBackground(Graphics graphics, int width, int height) {
// 背景を塗りつぶす
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, height);
// 妨害線を追加
for (int i = 0; i < 8; i++) {
graphics.setColor(RandomHelper.randomColor(40, 150));
Random random = new Random();
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
graphics.drawLine(x, y, x1, y1);
}
}
/**
* ランダムな文字列を生成する
*
* @param width 幅
* @param height 高さ
* @param os 出力ストリーム
* @return 生成された文字列
* @throws IOException 入出力例外
*/
@Override
public String generate(int width, int height, OutputStream os) throws IOException {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
configureBackground(graphics, width, height);
String randomText = RandomHelper.randomString(CODE_LENGTH);
renderCharacters(graphics, randomText);
graphics.dispose();
ImageIO.write(image, "JPEG", os);
return randomText;
}
/**
* 認証コードを生成する
*
* @param width 幅
* @param height 高さ
* @return 認証コードオブジェクト
*/
@Override
public CaptchaCode generate(int width, int height) {
CaptchaCode captchaCode = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
String code = generate(width, height, baos);
captchaCode = new CaptchaCode();
captchaCode.setCode(code);
captchaCode.setImageBytes(baos.toByteArray());
} catch (IOException e) {
logger.error("認証コード生成エラー", e);
captchaCode = null;
}
return captchaCode;
}
/**
* 文字の色とサイズを設定する
*
* @param g グラフィックスオブジェクト
* @param randomText ランダム文字列
*/
private void renderCharacters(Graphics g, String randomText) {
char[] charArray = randomText.toCharArray();
for (int i = 0; i < charArray.length; i++) {
g.setColor(new Color(50 + RandomHelper.nextInt(100),
50 + RandomHelper.nextInt(100), 50 + RandomHelper.nextInt(100)));
g.setFont(new Font(FONT_FAMILIES[RandomHelper.nextInt(FONT_FAMILIES.length)], Font.BOLD, 26));
g.drawString(String.valueOf(charArray[i]), 15 * i + 5, 19 + RandomHelper.nextInt(8));
}
}
}
4.ユーティリティクラス
package com.example.common;
import java.awt.*;
import java.util.Random;
public class RandomHelper extends org.apache.commons.lang3.RandomUtils {
private static final char[] VALID_CHARS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',
'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9' };
private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private static Random random = new Random();
public static String randomString(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(String.valueOf(VALID_CHARS[random.nextInt(VALID_CHARS.length)]));
}
return sb.toString();
}
public static String randomNumericString(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(String.valueOf(DIGITS[random.nextInt(DIGITS.length)]));
}
return sb.toString();
}
public static Color randomColor(int min, int max) {
int minValue = min;
int maxValue = max;
if (minValue > 255) {
minValue = 255;
}
if (maxValue > 255) {
maxValue = 255;
}
return new Color(minValue + random.nextInt(maxValue - minValue),
minValue + random.nextInt(maxValue - minValue),
minValue + random.nextInt(maxValue - minValue));
}
public static int nextInt(int bound) {
return random.nextInt(bound);
}
}
上記のコードにより、認証コード生成機能は基本的に実装されました。次に、それを呼び出すためのコントローラが必要です。
@ApiOperation(value = "認証コードを取得")
@GetMapping("/captcha")
public void generateCaptcha(HttpServletRequest request, HttpServletResponse response) {
CaptchaGenerator generator = new SimpleTextCaptchaGenerator();
try {
// 幅と高さを設定
CaptchaCode captchaCode = generator.generate(80, 28);
String code = captchaCode.getCode();
LOGGER.info("生成された認証コード: {}", code);
// 認証コードをセッションに保存
request.getSession().setAttribute("captchaCode", code);
// レスポンスヘッダーを設定
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// コンテンツタイプを設定
response.setContentType("image/jpeg");
response.getOutputStream().write(captchaCode.getImageBytes());
response.getOutputStream().flush();
} catch (IOException e) {
LOGGER.error("認証コード生成中にエラーが発生しました", e);
}
}
これでバックエンドの実装は完了です。次にフロントエンドのコードを記述します。
フロントエンドコード:
<html>
<body>
<div>
<input id="captchaInput" placeholder="認証コード" type="text" class=""
style="width:170px">
<!-- 認証コード表示 -->
<img onclick="refreshCaptcha()" id="captchaImage" style="margin-left: 20px;"/>
</div>
<script type="text/javascript">
refreshCaptcha();
/**
* 認証コードを取得して表示
*/
function refreshCaptcha() {
document.getElementById("captchaImage").src = addTimestamp("http://127.0.0.1:81/captcha");
}
// URLにタイムスタンプを追加
function addTimestamp(url) {
var timestamp = new Date().getTime();
if (url.indexOf("?") > -1) {
url = url + "×tamp=" + timestamp;
} else {
url = url + "?timestamp=" + timestamp;
}
return url;
};
</script>
</body>
</html>
これにより、画像をクリックして認証コードを更新できます。