LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

【C#】手機(jī)短信登錄開發(fā),還能這樣玩?

admin
2024年4月12日 23:15 本文熱度 1120

我們項(xiàng)目開發(fā)中比較通用的登錄方式是用賬號(hào)密碼登錄,但實(shí)際生活中短信登錄的方式是大家所常用的。

下面的文章,前三步我先進(jìn)行了短信登錄的實(shí)現(xiàn),最后一步對(duì)其進(jìn)行了異常處理封裝的細(xì)節(jié)優(yōu)化。

實(shí)現(xiàn)驗(yàn)證碼登錄流程分析

1)發(fā)送驗(yàn)證碼

用戶在提交手機(jī)號(hào)后,會(huì)校驗(yàn)手機(jī)號(hào)是否合法,如果不合法,則要求用戶重新輸入手機(jī)號(hào)。

如果手機(jī)號(hào)合法,后臺(tái)此時(shí)生成對(duì)應(yīng)的驗(yàn)證碼,同時(shí)將驗(yàn)證碼進(jìn)行保存,然后再通過短信的方式將驗(yàn)證碼發(fā)送給用戶。

2)短信驗(yàn)證碼登錄、注冊(cè)

用戶需輸入收到的驗(yàn)證碼及關(guān)聯(lián)的手機(jī)號(hào)碼。服務(wù)器后臺(tái)會(huì)從當(dāng)前的Session中提取先前存儲(chǔ)的驗(yàn)證碼,并與用戶所輸入的進(jìn)行比對(duì)。若兩者不匹配,用戶將無(wú)法完成驗(yàn)證過程。若驗(yàn)證碼相符,系統(tǒng)將依據(jù)用戶輸入的手機(jī)號(hào)碼在數(shù)據(jù)庫(kù)中進(jìn)行用戶查詢。若查詢結(jié)果顯示該手機(jī)號(hào)尚未注冊(cè),系統(tǒng)將自動(dòng)創(chuàng)建新的用戶賬戶,并將基礎(chǔ)信息存入數(shù)據(jù)庫(kù)。無(wú)論用戶是已存在或是新注冊(cè),系統(tǒng)都會(huì)更新 Session 信息,保存用戶的登錄憑證,以便用戶能夠順利進(jìn)行后續(xù)操作并隨時(shí)訪問其賬戶信息。

代碼實(shí)現(xiàn)驗(yàn)證碼發(fā)送

這里我使用 MyBatisX 實(shí)現(xiàn)項(xiàng)目的初始化。

1)正則表達(dá)式類

使用正則表達(dá)式分別對(duì)手機(jī)號(hào)、密碼、驗(yàn)證碼進(jìn)行校驗(yàn)。

正則表達(dá)式可以去網(wǎng)上找,我這里提供下我的實(shí)現(xiàn)方式,可以作為參考。

public class RegexPatterns {
    /**
     * 手機(jī)號(hào)正則
     */
    public static final String PHONE_REGEX="1\\d{10}";
    /**
     * 郵箱正則
     */
    public static final String EMAIL_REGEX="/^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$/";
    /**
     * 驗(yàn)證碼正則
     */
    public static final String VERIFY_CODE_REGEX="^[a-zA-Z\\d]{6}$";

}

2)正則校驗(yàn)工具類

對(duì) Controller 層傳入的手機(jī)號(hào)進(jìn)行校驗(yàn)。

滿足手機(jī)號(hào)正則表達(dá)式,手機(jī)號(hào) 11 位,并且只能為數(shù)字,才能校驗(yàn)通過

這里我使用的是 Hutool 工具類來(lái)校驗(yàn)手機(jī)號(hào)和驗(yàn)證碼是否合法。

我貼一下 Hutool 的官網(wǎng),有需要更加深層次了解的小伙伴可以訪問下哦!

Hutool 官網(wǎng):https://doc.hutool.cn/pages/index/

public class RegexUtils {

    /**
     * 校驗(yàn)手機(jī)號(hào)是否合法
     * @param phone
     * @return
     */
    public static boolean isPhoneInvalid(String phone){
        boolean matches = phone.matches(RegexPatterns.PHONE_REGEX);
        return matches;
    }

    /**
     * 校驗(yàn)驗(yàn)證碼是否合法
     * @param code
     * @return
     */
    public boolean isCodeInvalid(String code){
        boolean matches = code.matches(RegexPatterns.VERIFY_CODE_REGEX);
        return matches;
    }
}

3)Controller 層

@GetMapping("/code")
    public boolean SendCode(String phone, HttpSession session){
        boolean b = userService.sendCode(phone, session);
        return b;
    }

4)Service 層

首先,系統(tǒng)會(huì)將用戶輸入的手機(jī)號(hào)通過正則表達(dá)式校驗(yàn)工具類進(jìn)行驗(yàn)證,確保其格式正確無(wú)誤。一旦手機(jī)號(hào)通過校驗(yàn),程序便會(huì)自動(dòng)生成一個(gè)隨機(jī)驗(yàn)證碼,并將其安全地存儲(chǔ)在服務(wù)器的 Session 中。為了便于開發(fā)者實(shí)時(shí)監(jiān)控驗(yàn)證碼的生成和發(fā)送狀態(tài),系統(tǒng)特別設(shè)計(jì)了在控制臺(tái)以 debug 模式輸出驗(yàn)證碼的功能,從而確保了整個(gè)驗(yàn)證流程的透明度和可追蹤性。

@Resource
private UserService userService;

public boolean sendCode(String phone, HttpSession session) {
    //1、校驗(yàn)手機(jī)號(hào)是否合法
    if (!RegexUtils.isPhoneInvalid(phone)) {
        return false;
    }
    //2、生成隨機(jī)驗(yàn)證嗎
    String code = RandomUtil.randomNumbers(6);
    //3、保存驗(yàn)證碼
    session.setAttribute("code",code);
    //4、打印日志
    log.debug("發(fā)送短信驗(yàn)證碼成功,驗(yàn)證碼:{}",code);
    return true;
}

注意:這里需要開啟 debug 日志

controller 層中加入@Slf4j注解

logging:
  level:
    com.example: debug
# 開啟debug日志

結(jié)果:

實(shí)現(xiàn)驗(yàn)證碼登錄注冊(cè)

短信驗(yàn)證登錄注冊(cè)邏輯:

1、校驗(yàn)手機(jī)號(hào)

2、校驗(yàn)驗(yàn)證碼(取出 Session 中保存的驗(yàn)證碼與表單中的輸入的驗(yàn)證碼嗎進(jìn)行比較)

3、不一致:報(bào)錯(cuò)

4、一致:根據(jù)手機(jī)號(hào)查詢用戶

5、判斷用戶是否存在

6、不存在,根據(jù)手機(jī)號(hào)創(chuàng)建新用戶并保存

  • 用戶是憑空創(chuàng)建的,所以密碼可以沒有,

  • 用戶呢稱和頭像都是隨機(jī)默認(rèn)的

7、保存用戶信息到 Session 中

1)Controller 層

我們登錄需要獲取兩個(gè)參數(shù),用戶名和手機(jī)號(hào),根據(jù)手機(jī)號(hào)來(lái)創(chuàng)建用戶名。

@PostMapping("/login")
    public boolean login(LoginFormDTO loginFormDTO, HttpSession session){
        boolean login = userService.Login(loginFormDTO, session);
        return login;
    }

為了使代碼更加美觀,創(chuàng)建一個(gè)參數(shù)封裝類。

/**
 * 用戶登錄請(qǐng)求參數(shù)封裝類
 */
@Data
public class LoginFormDTO {
    private String code;
    private String phone;
}

2)Servcie 層

  /**
     * 用戶登錄
     * @param loginFormDTO
     * @param session
     * @return
     */
    @Override
    public boolean Login(LoginFormDTO loginFormDTO, HttpSession session) {
        //1、首先校驗(yàn)手機(jī)號(hào)和驗(yàn)證碼是否合法
        String phone = loginFormDTO.getPhone();
        if(!RegexUtils.isPhoneInvalid(phone)){
            return false;
        }
        //2、校驗(yàn)驗(yàn)證碼
        Object cachecode = session.getAttribute("code");
        String dtoCode = loginFormDTO.getCode();
        if (dtoCode==null&&!dtoCode.equals(cachecode)) {
            return false;
        }
        //3、根據(jù)手機(jī)號(hào)查詢用戶信息
        QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
        queryWrapper.eq("phone", phone);
        //4、根據(jù)查詢條件查詢數(shù)據(jù)庫(kù)中滿足以上條件的用戶
        User user = userMapper.selectOne(queryWrapper);
        if (user==null) {
            //創(chuàng)建用戶
            user=CreateUser(phone);
        }
        //5、保存用戶信息到session中
        session.setAttribute("user",user);
        return true;
    }

將創(chuàng)建用戶的這段代碼單獨(dú)封裝為一個(gè)函數(shù)。

    /**
     * 創(chuàng)建用戶
     * @param phone
     * @return
     */
    private User CreateUser(String phone){
        User user = new User();
        user.setPhone(phone);
        user.setNickName(RandomUtil.randomString(10));
        //保存用戶
        save(user);
        return user;
    }

發(fā)送驗(yàn)證碼

get  http://localhost:8080/api/user/code?phone=13177576913

校驗(yàn)驗(yàn)證碼并登錄

post http://localhost:8080/api/user/login?phone=13177576913
&code=686422

運(yùn)行結(jié)果:

優(yōu)化:全局通用返回對(duì)象

前面我的測(cè)試前端返回的數(shù)據(jù)都太過單調(diào),因?yàn)檫@是一個(gè)功能的實(shí)現(xiàn),并不是做一個(gè)完整的項(xiàng)目,但這樣看起來(lái)確實(shí)不太美觀。

所以這里使用 ==》全局統(tǒng)一 API 響應(yīng)框架 ==》對(duì)整個(gè)接口進(jìn)行統(tǒng)一的異常處理封裝,這樣就不需要寫那么多的異常處理類了。

1)引入依賴

使用rest-api-spring-boot-starter這個(gè)依賴,不用打開 Redis ,但這個(gè)依賴需要加上。

<!--RestfulAPI-->
<dependency>
    <groupId>cn.soboys</groupId>
    <artifactId>rest-api-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2)注解

啟動(dòng)類上加上這個(gè)@EnableRestFullApi 注解。

只需要引入依賴和加上注解這兩步,Log 日志就變得與上面沒優(yōu)化前的不一樣了。

注意:這里的端口號(hào)是 8000,也就是說(shuō)使用這個(gè)依賴必須要 8000 端口,我們?cè)谂渲梦募兴O(shè)置的 Web 端口沒有用了,無(wú)法自定義端口

運(yùn)行后,通過 Postman 測(cè)試,測(cè)試結(jié)果如下圖所示:

3)用戶信息脫敏

我們這里進(jìn)行用戶脫敏,將返回對(duì)象單獨(dú)封裝。

@Data
public class UserDTO {
    private Long id;
    private String nickName;
    private String icon;
}

修改登錄login方法中的下面所示內(nèi)容。

/**
     * copyProperties:屬性拷貝——把user中的屬性字動(dòng)拷貝到UserDTO中
     * BeanUtils:使用的是包c(diǎn)n.hutool.core.bean下的工具類
     */
//5、保存用戶信息到session中
UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
session.setAttribute("user", userDTO);

最終,如下圖所示成功返回三個(gè)信息。

以上,就是今天的分享,希望對(duì)大家有幫助。


該文章在 2024/4/12 23:15:39 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
婷五月亚洲中文 | 久久不射视频网 | 伊人丁香五月综合婷婷 | 亚洲成l人在线观看线路 | 亚洲欧美综合国产精品一区看三级 | 小说区图片区综合久久亚洲 |