中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java如何實現短信驗證碼登錄功能

發布時間:2022-03-03 15:17:35 來源:億速云 閱讀:872 作者:小新 欄目:開發技術

小編給大家分享一下java如何實現短信驗證碼登錄功能,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

業務案例

如下所示,是一個大家熟知的采用短信登錄的入口

java如何實現短信驗證碼登錄功能

輸入手機號之后,出現如下效果,

java如何實現短信驗證碼登錄功能

輸入手機上面收到的驗證碼之后,就可以正常登錄了

業務關鍵點剖析

以上是一個正常的使用短信驗證碼登錄的業務流程,在實際開發中,需要考慮的因素更多了,比如:

  • 驗證碼位數如何

  • 驗證碼如何存儲

  • 如何預防短信被刷

  • 倒計時功能,前后端如何配合

其實來說,短信驗證碼功能并不難,難得是如何做到業務場景的全面覆蓋和功能細節上面的考慮

短信驗證碼功能實現思路

小編結合實際經驗和調研,目前比較流行的做法是,使用redis做短信驗證碼,想必說到這里,懂行的同學們應該猜到了

完整的業務邏輯大概如下:

java如何實現短信驗證碼登錄功能

依據這個業務邏輯的實現思路,我們大致可以理清代碼的編寫邏輯,在小編開發過程中,其中有一個點遇到了一點梗,就是關于驗證碼的有效期的問題,主要考慮下面2點:

  • 后端存儲驗證碼有效期時長

  • 前端頁面倒計時和后端有效期的關系

有效期問題

java如何實現短信驗證碼登錄功能

java如何實現短信驗證碼登錄功能

下面我們編寫代碼來演示下完整的過程

前置準備:搭建一個springboot工程

操作步驟

1、導入核心依賴

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

2、編寫獲取短信驗證碼方法

@Service
public class SmsServiceImpl implements SmsService {

    public static final String VERIFY_CODE = "login:verify_code:";

    @Autowired
    private DbUserMapper dbUserMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public String getSmsVerifyCode(String phone) {
        if (StringUtils.isEmpty(phone)) {
            throw new RuntimeException("用戶手機號為空");
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("mobile",phone);
        DbUser dbUser = dbUserMapper.selectOne(queryWrapper);
        if(dbUser == null){
            throw new RuntimeException("用戶不存在");
        }
        String smsVerifyCode = getSmsVerifyCode();
        String smsCodeKey = VERIFY_CODE + dbUser.getUserId();
        String existedSmsCode = redisTemplate.opsForValue().get(smsCodeKey);
        //如果驗證碼已經存在時
        if (StringUtils.isNotEmpty(existedSmsCode)) {
            Long expireTime = redisTemplate.opsForValue().getOperations().getExpire(smsCodeKey);
            long lastTime = 60 * 3 - expireTime;
            //三分鐘內驗證碼有效,1分鐘到3分鐘之間,用戶可以繼續輸入驗證碼,也可以重新獲取驗證碼,新的驗證碼將覆蓋舊的
            if(lastTime > 60 && expireTime >0){
                //調用第三方平臺發短信,只有短信發送成功了,才能將短信驗證碼保存到redis
                System.out.println("此處調用短信發送邏輯......");
                redisTemplate.opsForValue().set(smsCodeKey, smsVerifyCode, 60 * 3, TimeUnit.SECONDS);
                System.out.println("短信驗證碼:" + smsVerifyCode);
            }
            //一分鐘之內不得多次獲取驗證碼
            if(lastTime < 60){
                throw new RuntimeException("操作過于頻繁,請一分鐘之后再次點擊發送");
            }
        }else {
            //調用notify服務發送短信,只有notify的短信發送成功了,才能將短信驗證碼保存到redis
            System.out.println("此處調用短信發送邏輯......");
            System.out.println("短信驗證碼:" + smsVerifyCode);
            redisTemplate.opsForValue().set(smsCodeKey, smsVerifyCode, 60 * 3, TimeUnit.SECONDS);
        }
        return smsVerifyCode;
    }

    /**
     * 隨機獲取6位短信數字驗證碼
     *
     * @return
     */
    public static String getSmsVerifyCode() {
        Random random = new Random();
        String code = "";
        for (int i = 0; i < 6; i++) {
            int rand = random.nextInt(10);
            code += rand;
        }
        return code;
    }

}

發送短信驗證碼需充分考慮幾個場景:

  • 首次輸入手機號,獲取驗證碼時,后端設置驗證碼有效期為3分鐘,前端倒計時1分鐘

  • 1分鐘之內,用戶不能第二次獲取驗證碼,1分鐘之后,用戶可以重新獲取驗證碼

  • 超過1分鐘后,同一個用戶再次點擊獲取驗證碼時,后端需主動移除redis存儲的上一次驗證碼

  • 3分鐘有效期內,用戶可隨時輸入第一次的驗證碼進行登錄

  • 登錄成功后,登錄接口需主動移除redis中的驗證碼

以上為驗證碼的核心業務方法,下面再編寫一個登錄的方法,當基礎校驗和驗證碼校驗通過后,即可登錄

	@Override
    public String login(String userId, String smsCode) {
        if (StringUtils.isEmpty(userId)) {
            throw new RuntimeException("用戶ID必傳");
        }
        if (StringUtils.isEmpty(smsCode)) {
            throw new RuntimeException("驗證碼不能為空");
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id",userId);
        DbUser dbUser = dbUserMapper.selectOne(queryWrapper);
        if(dbUser == null){
            throw new RuntimeException("用戶不存在");
        }
        //校驗驗證碼
        String smsCodeKey = VERIFY_CODE + dbUser.getUserId();
        String verifyCode = redisTemplate.opsForValue().get(smsCodeKey);
        if (StringUtils.isEmpty(verifyCode)) {
            throw new RuntimeException("短信驗證碼不存在或已過期");
        }
        if (!StringUtils.equals(smsCode, verifyCode)) {
            throw new RuntimeException("短信驗證碼錯誤");
        }
        //TODO 其他待驗證的登錄業務邏輯
        System.out.println("執行其他業務......");
        System.out.println("登錄成功");
        //最后清理下驗證碼
        if(redisTemplate.hasKey(smsCodeKey)){
            redisTemplate.delete(smsCodeKey);
        }
        return "login success";
    }

3、提供獲取驗證碼和登錄接口

@RestController
public class SmsController {

    @Autowired
    private SmsService smsService;

    @GetMapping("get/sms_code")
    public String getSmsVerifyCode(@RequestParam("phone") String phone){
        return smsService.getSmsVerifyCode(phone);
    }

    /**
     * 登錄
     * @param userId
     * @param smsCode
     * @return
     */
    @GetMapping("/login")
    public String login(@RequestParam("userId") String userId,@RequestParam("smsCode") String smsCode){
        return smsService.login(userId,smsCode);
    }

}

啟動redis服務,啟動項目,數據庫提前準備一條數據

java如何實現短信驗證碼登錄功能

場景測試1:獲取驗證碼

java如何實現短信驗證碼登錄功能

java如何實現短信驗證碼登錄功能

調用登錄接口,使用上面的驗證碼:

java如何實現短信驗證碼登錄功能

場景測試2:1分鐘內多次獲取驗證碼

第一次獲取驗證碼

java如何實現短信驗證碼登錄功能

再次獲取驗證碼

java如何實現短信驗證碼登錄功能

java如何實現短信驗證碼登錄功能

超過1分鐘少于3分鐘內,再次獲取驗證碼,得到新的驗證碼,同時redis中存儲的是最新的驗證碼

java如何實現短信驗證碼登錄功能

java如何實現短信驗證碼登錄功能

場景測試3:登錄輸入錯誤驗證碼

java如何實現短信驗證碼登錄功能

java如何實現短信驗證碼登錄功能

總體來說,使用redis實現短信驗證碼登錄的功能不算太復雜,主要是需要全面的考慮到各自使用場景即可

以上是“java如何實現短信驗證碼登錄功能”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

讷河市| 宜川县| 崇礼县| 临澧县| 星座| 崇信县| 保德县| 阿城市| 高尔夫| 古蔺县| 淮南市| 宜兰县| 泰州市| 陇西县| 乌审旗| 平潭县| 太仆寺旗| 饶平县| 嵩明县| 大城县| 杭锦旗| 静安区| 武义县| 光泽县| 修水县| 绩溪县| 广德县| 新邵县| 浮梁县| 安溪县| 屯门区| 平利县| 蓝田县| 福安市| 额济纳旗| 保亭| 富平县| 定陶县| 河北区| 浦县| 汤阴县|