오늘은 Spring에서 API를 사용하지 않고 Google OTP QR코드 자체 생성하는 소스를
포스팅 하려고 합니다.
기존에 사용하던 프로젝트 소스에서 Google OTP QR코드를 google API를 통해 생성하고
관리 및 인증은 소스와 DB에서 진행을 했는데 얼마전 google API에서 OTP QR코드 생성 API를 지원 종료 했습니다.
해당 API 주소는 다음과 같습니다.
(https://chart.googleapis.com/)
(https://chart.apis.google.com/)
2개의 주소 모두 사용 가능한 API 규격이였는데 현재는 다음과 같이 API 페이지가 404로 나옵니다.
현재 프로젝트에서 소스를 많이 변경하지 않고 google OTP QR코드만 생성하여
관리 및 인증부분은 소스 변경 없이 기존과 유지 할 수 있도록,
google OTP QR코드 API에서 생성하던 알고리즘을 그대로 개발하였습니다.
google OTP는 totp 인증 방식이기 때문에 관련 lib 설치가 필요합니다.
저는 Spring boot 에서 gradle를 사용하기 때문에 다음과 같이 totp 개발을 위한 lib을 설치하였습니다.
[gradle]
// https://mvnrepository.com/artifact/dev.samstevens.totp/totp
implementation 'dev.samstevens.totp:totp:1.7.1'
// https://mvnrepository.com/artifact/com.google.zxing/core
implementation 'com.google.zxing:core:3.5.3'
// https://mvnrepository.com/artifact/com.google.zxing/javase
implementation 'com.google.zxing:javase:3.5.3'
google OTP QRcode 생성하는 totp 관련 소스는 다음과 같습니다.
import org.apache.commons.codec.binary.Base32;
import dev.samstevens.totp.code.HashingAlgorithm;
import dev.samstevens.totp.exceptions.QrGenerationException;
import dev.samstevens.totp.qr.QrData;
import dev.samstevens.totp.qr.QrGenerator;
import dev.samstevens.totp.qr.ZxingPngQrGenerator;
import static dev.samstevens.totp.util.Utils.getDataUriForImage;
public String createOtp(String userId){
OtpDomain otpDomain = new OtpDomain();
byte[] buffer = new byte[5 + 5 * 5];
// Filling the buffer with random numbers.
// Notice: you want to reuse the same random generator
// while generating larger random number sequences.
new Random().nextBytes(buffer);
// Getting the key and converting it to Base32
Base32 codec = new Base32();
byte[] secretKey = Arrays.copyOf(buffer, 5);
byte[] bEncodedKey = codec.encode(secretKey);
// 생성된 Key는 DB에 저장하여 인증시 사용
String encodedKey = new String(bEncodedKey);
String issuer = "OTP NAME";
// QrCode 이미지 생성 규격
QrData data = new QrData.Builder()
.label(userId)
.secret(encodedKey)
.issuer(issuer)
.algorithm(HashingAlgorithm.SHA1)
.digits(6)
.period(30)
.build();
QrGenerator qrGenerator = new ZxingPngQrGenerator();
byte[] imageData = null;
try {
imageData = qrGenerator.generate(data);
}catch (QrGenerationException e) {
throw new CustomException(e);
}
String mimeType = qrGenerator.getImageMimeType();
String otpDataUri = getDataUriForImage(imageData, mimeType);
otpDomain.setUserId(userId);
otpDomain.setOtpEncodeKey(encodedKey);
otpDomain.setQrCodeUrl(otpDataUri);
otpMapper.saveOtp(otpDomain);
return otpDataUri;
}
생성된 otpDataUri를 보면 다음과 같이 data URI를 통해 QR코드를 확인할 수 있습니다.
별도의 image가 생성된는 것이 아닌, url : data:image/png;base64,~#~#~# 형태로 사용할 수 있는 data이기 때문에,
별도의 image 저장 없이 활용할 수 있습니다.
data URI란 RFC 2397에 정의되어 있으며 이미지 등의 외부 바이너리 파일을 웹페이지에 인라인으로 넣기 위해 사용합니다. data URI는 이미지 말고도 여러타입을 넣을 수 있으며, URLEncoding방식을 이용해 텍스트나 스크립트를 만들어 넣을 수도 있고, Base64를 이용해 이미지를 만들어 쓸 수도 있습니다. |
해당 포스팅은 google OTP QR코드 생성 API -> google OTP QR코드 자체 생성의 의미가 큰 부분입니다.
전체적인 생성, 인증 부분은 추후에 정리해서 다시 포스팅 하도록 하겠습니다.
'Develope > Spring' 카테고리의 다른 글
[Spring] JpaRepository where에 List 사용 방법 (3) | 2024.04.18 |
---|---|
[SpringBoot] 엑셀(Excel) 파일 업로드 방법(poi 라이브러리) (18) | 2020.02.14 |
[SpringBoot] Ajax 배열, 리스트로 값 넘기기 (0) | 2020.02.14 |
[SpringBoot] mysql jdbc driver 설정 및 사용방법 (0) | 2020.02.14 |
[Spring] @RequestMapping produces를 이용한 Response Content-Type 변경 (0) | 2019.09.20 |