Spring Boot

Spring-boot 핸드폰 인증(Colsms + Redis)

zee0541 2025. 1. 8. 16:27

이 api 는 복잡하다...

 

https://coolsms.co.kr/

 

세상에서 가장 안정적이고 빠른 메시지 발송 플랫폼 - 쿨에스엠에스

손쉬운 결제 전용계좌, 신용카드, 계좌이체 등 국내 결제 뿐만 아니라 해용신용카드로 한번의 카드번호 등록으로 자동충전까지 지원합니다. 전용계좌, 신용카드, 계좌이체 등 다양한 결제 방식

coolsms.co.kr

회원가입 하면

api key

api secret 

를 발급 받을 수 있다.

 

Redis 설치

https://github.com/microsoftarchive/redis

 

GitHub - microsoftarchive/redis: Redis is an in-memory database that persists on disk. The data model is key-value, but many dif

Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes - microsoftarchive/redis

github.com

 

 

 https://pamyferret.tistory.com/9

<출처>

 

[ Redis ] Window에 redis 설치해서 사용하기

스프링 부트의 캐싱 기능을 사용하다보니 분산 캐싱 기능도 사용해보고 싶어졌다. 분산 캐싱에 사용할 캐시 데이터 저장 공간은 여러 가지를 사용하는데, 그 중 Redis라는 것을 사용해보려고 한

pamyferret.tistory.com

 

 

방식이 잘 되어있어서 출처 로 남기겠습니다!

 

application.properties

#coolsms
coolsms.api.key={api key}
coolsms.api.secret={pai secret}
coolsms.api.number= {user_phone}

#redis
spring.data.redis.host=localhost
spring.data.redis.port=6379   // 고정

 

 

 

build.fradle

//sms 인증번호
	implementation group: 'net.nurigo', name: 'javaSDK', version: '2.2' // 다른 분들도 이것만 사용한다
    
	implementation 'org.springframework.boot:spring-boot-starter-data-redis'

 

RedisConfig

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);

        // Key와 Value를 String으로 저장하도록 Serializer 설정
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());

        return redisTemplate;
    }

}

 

Redis와 통신하기 위한 설정 이다.

 

이 설정을 통해 Key-Value 형태로 데이터를 쉽게 저장하고 가져올 수 있는 환경을 제공한다.

 

UserFormDto

private String phoneVerificationCode; // 핸드폰 인증 번호

 

추가한다.

 

CoolSmsService

@Service
@Log4j2
public class CoolSmsService {

   @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Value("${coolsms.api.key}")
    private String apiKey;

    @Value("${coolsms.api.secret}")
    private String apiSecret;

    @Value("${coolsms.api.number}")
    private String fromPhoneNumber;

    private static final String REDIS_SMS_PREFIX = "SMS_";


    public void sendSmsWithCode(String to) {
        try {
            // 4자리 인증번호 생성
            String verificationCode = generateRandomNumber();

            // Coolsms API 호출 준비
            Message coolsms = new Message(apiKey, apiSecret);

            HashMap<String, String> params = new HashMap<>();
            params.put("to", to);
            params.put("from", fromPhoneNumber);
            params.put("type", "sms");
            params.put("text", "인증번호는 [" + verificationCode + "] 입니다.");

            // API 호출
            JSONObject response = coolsms.send(params);
            System.out.println("Coolsms API Response: " + response.toString());

            // 성공 여부 확인 (Long으로 캐스팅 후 int 변환)
            long successCountLong = (long) response.get("success_count");
            int successCount = Math.toIntExact(successCountLong);

            if (successCount > 0) {
                // 성공 처리: Redis에 인증번호 저장
                redisTemplate.opsForValue().set(REDIS_SMS_PREFIX + to, verificationCode, Duration.ofMinutes(5));
            } else {
                // 실패 처리
                String errorMessage = response.get("result_message") != null
                        ? response.get("result_message").toString()
                        : "Unknown error";
                System.err.println("Coolsms Error: " + errorMessage);
                throw new RuntimeException("Failed to send SMS: " + errorMessage);
            }
        } catch (Exception e) {
            System.err.println("Coolsms Exception: " + e.getMessage());
            throw new RuntimeException("Failed to send SMS", e);
        }
    }

    public boolean verifyCode(String phoneNumber, String code) {
        String storedCode = redisTemplate.opsForValue().get(REDIS_SMS_PREFIX + phoneNumber);
        return storedCode != null && storedCode.equals(code);
    }

    private String generateRandomNumber() {
        return String.format("%04d", new Random().nextInt(10000)); // 4자리 숫자 생성
    }
}

 

 

SmsController

@RestController
@RequestMapping("/api/sms")
public class SmsController {

    @Autowired
    private CoolSmsService coolSmsService;

    @PostMapping("/send")
    public String sendSms(@RequestParam String phoneNumber) {
        try {
            coolSmsService.sendSmsWithCode(phoneNumber);
            return "SMS 인증번호가 전송되었습니다.";
        } catch (Exception e) {
            return "SMS 전송에 실패했습니다. 오류: " + e.getMessage();
        }
    }

    @PostMapping("/verify")
    public String verifySms(@RequestParam String phoneNumber, @RequestParam String code) {
        boolean isValid = coolSmsService.verifyCode(phoneNumber, code);
        return isValid ? "인증 성공" : "인증 실패: 잘못된 인증번호입니다.";
    }

}

 

 

이렇게 하면

Coolsms API Response: {"group_id":"R2G4bTFhDQWudVGn","success_count":1,"error_count":0}


이렇게 나오면 성공이다.

 

-결과-

 

인증 번호가 온다

 

문자는 오는데 에러 나고 4번째 성공했다.