SoFunction
Updated on 2025-04-14

Redis prevents malicious calls from SMS

1. Scene

In the login or registration interface, when using the SMS verification code scenario, a malicious call to the SMS interface is encountered, and multiple calls are made in a millisecond, resulting in a significant consumption of SMS resources.

2. Troubleshooting

After investigation, it was found that the SMS sending interface was unlimited, and only the verification code was retained for sending information through Redis. A timestamp is generated several times or even more than a dozen times. After multiple threads access redis at the same time, the values ​​are the same, and all pass verification to call the SMS interface.

3. Solution

Use redis distributed lock to solve this problem.

The relevant codes are as follows:

3.1 Redis lock implementation

public class RedisLock {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final Long NX = 1L; // Timeout time
    public boolean tryLock(String key, String value) {
		// Timeout time unit, it is found here that in the newer version of RedisTemplate, the time unit of the setIfAbsent method is TimeUnit, which is not the Long type expressed in most posts        TimeUnit timeUnit = ; 

        // Here is the redis lock timeout time is set to 1 minute        Boolean result = ().setIfAbsent(key, value, NX, timeUnit);
        return result != null && result;
    }

    // The unlock method has not been tested, please test it before using it    public void unlock(String key, String value) {
        String script = "if ('get', KEYS[1]) == ARGV[1] then " +
                "return ('del', KEYS[1]) " +
                "else " +
                "return 0 " +
                "end";
        ((RedisCallback<Boolean>) connection -> {
            Object nativeConnection = ();
            if (nativeConnection instanceof Jedis) {
                return ((Jedis) nativeConnection).eval(script, (key), (value)).equals(1L);
            } else if (nativeConnection instanceof RedisClusterConnection) {
                return ((RedisClusterConnection) nativeConnection).eval((), , 1, (), ()).equals(1L);
            }
            return false;
        });
    }
}

3.2 Method Call

	public boolean getVerfityCode(String mobile) {

        String smsCode = ();

        // Redis lock parameters        String lockKey = "sms_lock_" + mobile;
        String lockValue = ().toString();

        boolean send = false;

        try {
            if ((lockKey, lockValue)) {
                // Acquisition of the lock is successful and triggers the SMS verification code function (specific logic, here it is preserved because the original login logic requires redis support)                String s = (RedisKeys.VERFITY_CODE + mobile);
                if (s != null) {
                    // Determine whether the verification code expires                    throw new ServiceException("The verification code has not expired, please do not re-obtain it");
                }
                // Send verification code                send = (mobile, smsCode);
                if (send) {
                    // It does not exist in reids. The corresponding verification code for this phone is verCodeTm seconds. You can regenerate it.                    (RedisKeys.VERFITY_CODE + mobile, smsCode, verCodeTm);
        }
            }
        } catch (Exception e) {
            send = false;
        }
        // Many posts will add finally unlocking logic here. In order to ensure that malicious calls to text messages will not be triggered within 1 minute, the unlocking logic will be cancelled and will be automatically unlocked after being destroyed by redis timeout.        return send;
    }

This is the end of this article about the implementation of redis preventing malicious calls to text messages. For more related content related to redis preventing malicious calls to text messages, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!