-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#26 Feat: 메타데이터를 통한 여권 유효성 검사 & 재학증StudentCertification 인증시간 추가 [박한솔]
- Loading branch information
Showing
9 changed files
with
259 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,11 +4,11 @@ VALUES | |
('[email protected]', '$2a$10$EXAMPLEHASHFORUSERPASSWORD'), | ||
('3751271433', '$2a$10$skVt4kLn.95UGnrasmxQku5AGhhg6fESNtg/Ndw3iBQin.SqHrIdK'); | ||
|
||
|
||
INSERT INTO wallets (user_id, pdfUrl,privateKey, publicKey) | ||
VALUES | ||
(1,'https://basilium-product-bucket.s3.ap-northeast-2.amazonaws.com/1_certifications.pdf','privateKeyForUser1', 'publicKeyForUser1'), | ||
(2,null,'privateKeyForUser2', 'publicKeyForUser2'), | ||
(3,null,'privateKeyForUser2', 'publicKeyForUser2'); | ||
|
||
|
||
|
Binary file modified
BIN
+338 Bytes
(100%)
web3-credential-server/build/tmp/compileJava/previous-compilation-data.bin
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
web3-credential-server/src/main/java/web3/controller/cert/PassportController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package web3.controller.cert; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import reactor.core.publisher.Mono; | ||
import web3.service.cert.PassportService; | ||
import web3.service.dto.cert.PassportRequestDto; | ||
|
||
import java.io.IOException; | ||
import java.util.Base64; | ||
|
||
@RestController | ||
@RequestMapping("/api/passport") | ||
public class PassportController { | ||
|
||
private final PassportService passportService; | ||
|
||
public PassportController(PassportService passportService) { | ||
this.passportService = passportService; | ||
} | ||
|
||
@Operation(summary = "여권 유효성 검사", description = "여권의 유효성을 검사합니다.") | ||
@PostMapping("/check-validity") | ||
public Mono<ResponseEntity<String>> checkPassportValidity( | ||
@Parameter(description = "여권 요청 정보", required = true) | ||
@RequestParam("certFile") MultipartFile certFile, | ||
@RequestParam("keyFile") MultipartFile keyFile, | ||
@RequestParam("certPassword") String certPassword, | ||
@RequestParam("userName") String userName, | ||
@RequestParam("identity") String identity, | ||
@RequestParam("passportNo") String passportNo, | ||
@RequestParam("issueDate") String issueDate, | ||
@RequestParam("expirationDate") String expirationDate, | ||
@RequestParam("birthDate") String birthDate) { | ||
|
||
String certFileEncoded = encodeFileToBase64(certFile); | ||
String keyFileEncoded = encodeFileToBase64(keyFile); | ||
|
||
PassportRequestDto passportRequestDto = new PassportRequestDto(certFileEncoded, keyFileEncoded, certPassword, userName, identity, passportNo, issueDate, expirationDate, birthDate); | ||
|
||
return passportService.checkPassportValidity(passportRequestDto) | ||
.map(response -> ResponseEntity.ok("여권 유효성 검사 성공: " + response)) | ||
.onErrorReturn(ResponseEntity.badRequest().body("여권 유효성 검사에 실패했습니다.")); | ||
} | ||
|
||
private String encodeFileToBase64(MultipartFile file) { | ||
try { | ||
byte[] fileContent = file.getBytes(); | ||
return Base64.getEncoder().encodeToString(fileContent); | ||
} catch (IOException e) { | ||
throw new RuntimeException("파일 인코딩 실패", e); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
web3-credential-server/src/main/java/web3/service/cert/PassportService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package web3.service.cert; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.core.type.TypeReference; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
import reactor.core.publisher.Mono; | ||
import web3.service.dto.cert.PassportRequestDto; | ||
|
||
import javax.crypto.Cipher; | ||
import java.io.UnsupportedEncodingException; | ||
import java.net.URLDecoder; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.KeyFactory; | ||
import java.security.PublicKey; | ||
import java.security.spec.X509EncodedKeySpec; | ||
import java.util.Base64; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
@Service | ||
@Slf4j | ||
public class PassportService { | ||
|
||
private final WebClient webClient; | ||
private final WebClient webClientToken; // 액세스 토큰 요청을 위한 WebClient | ||
private static final String BASE_URL = "https://development.codef.io"; | ||
private static final String API_URL = "/v1/kr/public/mw/passport-data/status"; | ||
private static final String BASE_TOKEN_URL = "https://oauth.codef.io"; | ||
private static final String ACCESS_TOKEN_URL = "/oauth/token"; | ||
private static final String CLIENT_ID = "86640213-3b83-461a-97ab-2491d68a2052"; | ||
|
||
public PassportService(WebClient.Builder webClientBuilder) { | ||
this.webClient = webClientBuilder.baseUrl(BASE_URL).build(); | ||
this.webClientToken = webClientBuilder.baseUrl(BASE_TOKEN_URL).build(); // 수정된 부분 | ||
} | ||
|
||
// 액세스 토큰을 가져오는 메서드 | ||
private Mono<String> fetchAccessToken() { | ||
return webClientToken.post() | ||
.uri(ACCESS_TOKEN_URL) // 추가된 경로 | ||
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString((CLIENT_ID + ":" + CLIENT_SECRET).getBytes())) | ||
.header("Content-Type", "application/x-www-form-urlencoded") | ||
.bodyValue("grant_type=client_credentials&scope=read") | ||
.retrieve() | ||
.bodyToMono(Map.class) | ||
.map(response -> (String) response.get("access_token")) | ||
.doOnError(e -> log.error("Error fetching access token: {}", e.getMessage())); | ||
} | ||
|
||
// RSA 암호화 메서드 | ||
private String encryptRSAPassword(String password) throws Exception { | ||
byte[] keyBytes = Base64.getDecoder().decode(PUBLIC_KEY_STR); | ||
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBytes)); | ||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); | ||
cipher.init(Cipher.ENCRYPT_MODE, publicKey); | ||
return Base64.getEncoder().encodeToString(cipher.doFinal(password.getBytes(StandardCharsets.UTF_8))); | ||
} | ||
|
||
// 패스포트 유효성 검사 메서드 | ||
public Mono<Map<String, Object>> checkPassportValidity(PassportRequestDto passportRequestDto) { | ||
return fetchAccessToken() | ||
.flatMap(accessToken -> { | ||
try { | ||
Map<String, String> requestBody = createRequestBody(passportRequestDto); | ||
log.info("requestBody: {}", requestBody); | ||
return webClient.post() | ||
.uri(API_URL) | ||
.header("Authorization", "Bearer " + accessToken) | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.accept(MediaType.APPLICATION_JSON) | ||
.bodyValue(requestBody) | ||
.retrieve() | ||
.bodyToMono(String.class) | ||
.flatMap(responseBody -> { | ||
log.info("Response: {}", responseBody); | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
try { | ||
String decodedResponseBody = URLDecoder.decode(responseBody, StandardCharsets.UTF_8.name()); | ||
Map<String, Object> jsonResponse = objectMapper.readValue(decodedResponseBody, new TypeReference<Map<String, Object>>() {}); | ||
return Mono.just(jsonResponse); | ||
} catch (JsonProcessingException e) { | ||
log.error("Error processing JSON: {}", e.getMessage()); | ||
return Mono.error(e); // 예외를 반환 | ||
} catch (UnsupportedEncodingException e) { | ||
throw new RuntimeException(e); | ||
} | ||
}) | ||
.doOnError(e -> log.error("Error checking passport validity: {}", e.getMessage())); | ||
} catch (Exception e) { | ||
return Mono.error(e); | ||
} | ||
}); | ||
} | ||
|
||
private Map<String, String> createRequestBody(PassportRequestDto passportRequestDto) throws Exception { | ||
Map<String, String> requestBody = new HashMap<>(); | ||
requestBody.put("organization", "0002"); | ||
requestBody.put("loginType", "2"); | ||
requestBody.put("certType", "1"); | ||
requestBody.put("certFile", passportRequestDto.getCertFileEncoded()); | ||
requestBody.put("keyFile", passportRequestDto.getKeyFileEncoded()); | ||
requestBody.put("certPassword", encryptRSAPassword(passportRequestDto.getCertPassword())); | ||
requestBody.put("userName", passportRequestDto.getUserName()); | ||
requestBody.put("userName1", passportRequestDto.getUserName()); | ||
requestBody.put("identity", passportRequestDto.getIdentity()); | ||
requestBody.put("passportNo", passportRequestDto.getPassportNo()); | ||
requestBody.put("issueDate", passportRequestDto.getIssueDate()); | ||
requestBody.put("expirationDate", passportRequestDto.getExpirationDate()); | ||
requestBody.put("birthDate", passportRequestDto.getBirthDate()); | ||
return requestBody; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
web3-credential-server/src/main/java/web3/service/dto/cert/PassportRequestDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package web3.service.dto.cert; | ||
|
||
public class PassportRequestDto { | ||
private String certFileEncoded; // 인증서 파일 Base64 인코딩 | ||
private String keyFileEncoded; // 키 파일 Base64 인코딩 | ||
private String certPassword; // 인증서 비밀번호 | ||
private String userName; // 사용자 이름 | ||
private String identity; // 주민등록번호 | ||
private String passportNo; // 여권 번호 | ||
private String issueDate; // 발급일 | ||
private String expirationDate; // 만료일 | ||
private String birthDate; // 생년월일 | ||
|
||
public PassportRequestDto(String certFileEncoded, String keyFileEncoded, String certPassword, | ||
String userName, String identity, String passportNo, | ||
String issueDate, String expirationDate, String birthDate) { | ||
this.certFileEncoded = certFileEncoded; | ||
this.keyFileEncoded = keyFileEncoded; | ||
this.certPassword = certPassword; | ||
this.userName = userName; | ||
this.identity = identity; | ||
this.passportNo = passportNo; | ||
this.issueDate = issueDate; | ||
this.expirationDate = expirationDate; | ||
this.birthDate = birthDate; | ||
} | ||
|
||
// Getters | ||
public String getCertFileEncoded() { | ||
return certFileEncoded; | ||
} | ||
|
||
public String getKeyFileEncoded() { | ||
return keyFileEncoded; | ||
} | ||
|
||
public String getCertPassword() { | ||
return certPassword; | ||
} | ||
|
||
public String getUserName() { | ||
return userName; | ||
} | ||
|
||
public String getIdentity() { | ||
return identity; | ||
} | ||
|
||
public String getPassportNo() { | ||
return passportNo; | ||
} | ||
|
||
public String getIssueDate() { | ||
return issueDate; | ||
} | ||
|
||
public String getExpirationDate() { | ||
return expirationDate; | ||
} | ||
|
||
public String getBirthDate() { | ||
return birthDate; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,11 +4,9 @@ VALUES | |
('[email protected]', '$2a$10$EXAMPLEHASHFORUSERPASSWORD'), | ||
('3751271433', '$2a$10$skVt4kLn.95UGnrasmxQku5AGhhg6fESNtg/Ndw3iBQin.SqHrIdK'); | ||
|
||
|
||
INSERT INTO wallets (user_id, pdfUrl,privateKey, publicKey) | ||
VALUES | ||
(1,'https://basilium-product-bucket.s3.ap-northeast-2.amazonaws.com/1_certifications.pdf','privateKeyForUser1', 'publicKeyForUser1'), | ||
(2,null,'privateKeyForUser2', 'publicKeyForUser2'), | ||
(3,null,'privateKeyForUser2', 'publicKeyForUser2'); | ||
|
||
|
||
|
||
(3,null,'privateKeyForUser2', 'publicKeyForUser2'); |