最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實現(xiàn)短信發(fā)送及手機驗證碼登錄

 更新時間:2023年07月18日 15:26:52   作者:我愛布朗熊  
本文主要介紹了SpringBoot實現(xiàn)短信發(fā)送及手機驗證碼登錄,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、短信發(fā)送

1.1 阿里云短信服務(wù)

短信服務(wù)_企業(yè)短信營銷推廣_驗證碼通知-阿里云

也可以在下面這個地方查看短信服務(wù) 

1.1.1 設(shè)置短信簽名

短信簽名就是短信發(fā)送者的署名,表示發(fā)送方的身份

1.1.2 模板管理

申請下來之后可以點擊詳情進行查看

其中模板CODE是自動生成的,不用管,重點是模板的內(nèi)容

1.1.3 設(shè)置AccessKey

創(chuàng)建新的用戶

勾選上之后,我們在編程代碼中就能使用

當(dāng)我們創(chuàng)建用戶成功后,就生成了一對AccessKey,即AccessKey ID(用戶名) 與AccessKey Secret(密碼)

很多人在這里的時候不小心沒截圖或者沒保存就關(guān)了,丟失了AccessKey,但是不要緊,還可以再次創(chuàng)建

還有就是如果別人知道了我們的AccessKey,那別人使用的時候會就花我們的錢。我們也可以把泄露的AccessKey禁用

之后再新增授權(quán)。這次授權(quán)的意思就是僅僅授予有關(guān)短信服務(wù)的,即是我們泄露了,別人也只能操作短信服務(wù),對我們的影響很小。

1.2 短信發(fā)送——代碼開發(fā)

參照官方文檔即可

新手指引_短信服務(wù)-阿里云幫助中心

1.2.1 導(dǎo)入maven坐標(biāo)

        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.16</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>2.1.0</version>
        </dependency>

1.2.2 調(diào)用API

 
/**
 * 短信發(fā)送工具類
 */
public class SMSUtils {
	/**
	 * 發(fā)送短信
	 * @param signName 簽名
	 * @param templateCode 模板
	 * @param phoneNumbers 手機號
	 * @param param 參數(shù)
	 */
	public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param){
		DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAI5tHRxs2FeCu5JcJTGbm2", "v0H4PaJpXSwNr6XChtlVYAgmQWgKRA");
		IAcsClient client = new DefaultAcsClient(profile);
		SendSmsRequest request = new SendSmsRequest();
		request.setSysRegionId("cn-hangzhou");
//	    要發(fā)送給那個人的電話號碼
		request.setPhoneNumbers(phoneNumbers);
//      我們在阿里云設(shè)置的簽名
		request.setSignName(signName);
//	    我們在阿里云設(shè)置的模板
		request.setTemplateCode(templateCode);
//	    在設(shè)置模板的時候有一個占位符
		request.setTemplateParam("{\"code\":\""+param+"\"}");
//		request.setPhoneNumbers("1368846****");//接收短信的手機號碼
//		request.setSignName("阿里云");//短信簽名名稱
//		request.setTemplateCode("SMS_20933****");//短信模板CODE
//		request.setTemplateParam("張三");//短信模板變量對應(yīng)的實際值
		try {
			SendSmsResponse response = client.getAcsResponse(request);
			System.out.println("短信發(fā)送成功");
		}catch (ClientException e) {
			e.printStackTrace();
		}
	}
}

1.3  手機驗證碼登錄

  • 方便、快捷、無需注冊、直接登陸
  • 使用短信驗證碼作為登錄憑證,無序記憶密碼
  • 安全

登錄流程:  輸入手機號  ->  獲取驗證碼  ->  輸入驗證碼  ->  點擊登錄  ->  登陸成功

注意: 通過手機驗證碼登錄,手機號是區(qū)分不同用戶的標(biāo)識

1.3.1 用戶數(shù)據(jù)庫表

因為是通過手機和驗證碼登錄的,所以沒有用戶名和密碼字段

1.3.2  修改過濾器

 在寫代碼之前記得要在過濾器中定義不需要處理的請求路徑/user/sendMsg和/user/login

 然后訪問路徑: http://localhost:8080/front/page/login.html

 
/**
 * 檢查用戶是否已經(jīng)完成登錄
 * 過濾器與攔截器的區(qū)別:Filter對所有訪問進行增強(在Tomcat服務(wù)器進行配置),Interceptor僅針對SpringMVC的訪問進行增強
 */
@Slf4j
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")  //urlPatterns指定攔截哪些路徑
public class LoginCheckFilter implements Filter {
    //  此對象的作用:路徑匹配器,  匹配路徑時支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//      servletRequest向下強制類型轉(zhuǎn)換
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //1. 獲取本次請求的URI( URI:請求的資源路徑)
        String requestURI = request.getRequestURI();
        log.info("攔截到請求:{}", request.getRequestURI());
        // 定義不用處理的請求路徑
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**",
                "/common/**",
                "/user/sendMsg",
                "/user/login"
        };
        //2. 判斷本次請求是否需要處理(因為有些請求并不需要用戶登錄)
        boolean check = check(requestURI, urls);
        //3.如果不需要處理,則直接放行
        if (check) {
            log.info("本次請求{}不需要處理", request.getRequestURI());
            filterChain.doFilter(request, response);
            return;
        }
        //4-1.判斷登錄狀態(tài),如果已登錄,則直接放行.從session中獲取用戶,如果獲取到說明已經(jīng)登錄
        if (request.getSession().getAttribute("employee") != null) {
            log.info("用戶已登錄,用戶id為{}", request.getSession().getAttribute("employee"));
            Long empId = (Long) request.getSession().getAttribute("employee");
            BaseContext.setCurrentId(empId);
            filterChain.doFilter(request, response);
            return;
        }
        //4-2.判斷登錄狀態(tài),如果已登錄,則直接放行.從session中獲取用戶,如果獲取到說明已經(jīng)登錄
        if (request.getSession().getAttribute("user") != null) {
            log.info("用戶已登錄,用戶id為{}", request.getSession().getAttribute("user"));
            Long userId = (Long) request.getSession().getAttribute("user");
            BaseContext.setCurrentId(userId);
            filterChain.doFilter(request, response);
            return;
        }
        //5.如果未登錄則返回未登錄結(jié)果
        log.info("資源路徑路徑:{},用戶未登錄{}", request.getRequestURI(), request.getSession().getAttribute("employee"));
//           通過輸出流的方式向客戶端響應(yīng)數(shù)據(jù)   (為什么要返回這個NOTLOGIN?  因為前端需要這個來進行判定是否登錄)
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
//        filterChain.doFilter(request, response);  加上這個就無法實現(xiàn)
    }
    /**
     * 檢查本次請求是否需要放行
     *
     * @param requestURI 請求的資源路徑
     * @param urls       放過的路徑
     * @return true 放行
     */
    public boolean check(String requestURI, String[] urls) {
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if (match) {
//           放行
                return true;
            }
        }
        return false;
    }
}

1.3.3   隨機生成驗證碼的工具類

/**
 * 隨機生成驗證碼工具類
 */
public class ValidateCodeUtils {
    /**
     * 隨機生成驗證碼
     * @param length 長度為4位或者6位
     * @return
     */
    public static Integer generateValidateCode(int length){
        Integer code =null;
//      長度為4
        if(length == 4){
            code = new Random().nextInt(9999);//生成隨機數(shù),最大為9999
            if(code < 1000){
                code = code + 1000;//保證隨機數(shù)為4位數(shù)字
            }
//      長度為6
        }else if(length == 6){
            code = new Random().nextInt(999999);//生成隨機數(shù),最大為999999
            if(code < 100000){
                code = code + 100000;//保證隨機數(shù)為6位數(shù)字
            }
//       其他情況
        }else{
            throw new RuntimeException("只能生成4位或6位數(shù)字驗證碼");
        }
        return code;
    }
    /**
     * 隨機生成指定長度字符串驗證碼
     * @param length 長度
     * @return
     */
    public static String generateValidateCode4String(int length){
        Random rdm = new Random();
        String hash1 = Integer.toHexString(rdm.nextInt());
        String capstr = hash1.substring(0, length);
        return capstr;
    }
}

1.3.4 手機驗證碼登錄-- 發(fā)送驗證碼

兩次ajax請求:

   1. 登錄頁面輸入手機號,點擊【獲取驗證碼】按鈕,頁面發(fā)送ajax請求,在服務(wù)端調(diào)用短信服務(wù)API給指定手機號發(fā)送驗證碼短信

   2. 在登錄頁面輸入驗證碼,點擊【登錄】按鈕,發(fā)送ajax請求,在服務(wù)端處理登錄請求

    @PostMapping("/sendMsg")
    public R<String> sendMsg(@RequestBody User user, HttpSession session){
//      1.獲取手機號
        String phone = user.getPhone();
        if(StringUtils.isEmpty(phone)){
            return R.error("短信發(fā)送失敗");
        }
//      2.隨機生成四位驗證碼
        String code = ValidateCodeUtils.generateValidateCode(4).toString();
//      3.調(diào)用阿里云提供的短信服務(wù)
        SMSUtils.sendMessage("張靖奇","",phone,code);
//      4.需要將生成的驗證碼保存到session中
         session.setAttribute(phone,code);
        return R.success("驗證碼短信發(fā)送成功");
    }

1.3.5 手機驗證碼登錄-- 驗證驗證碼

    //  其實傳過來的phone:xxxx,code:xxx 也可以用map集合接收
    @PostMapping("/login")
    public R<User> login(@RequestBody Map map, HttpSession session) {
        log.info(map.toString());
//      1. 獲取手機號
        String phone = map.get("phone").toString();
//      2. 獲取驗證碼
        String code = map.get("code").toString();
//      3. 從Session中獲取保存的驗證碼
        Object codeInSession = session.getAttribute(phone);
//      4. 進行驗證碼比對(頁面提交的驗證碼和Session中保存的驗證碼比對)
        if (codeInSession != null && codeInSession.equals(code)) {
//          5.對比成功,說明登錄成功
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getPhone,phone);
            User user = userService.getOne(queryWrapper);
            if (user==null){
//          6. 如果新用戶,自動注冊
                user = new User();
                user.setPhone(phone);
                user.setStatus(1);
               userService.save(user);
            }
            session.setAttribute("user",user.getId());
            return R.success(user);
        }
        return R.error("登錄失敗");
    }

到此這篇關(guān)于SpringBoot實現(xiàn)短信發(fā)送及手機驗證碼登錄的文章就介紹到這了,更多相關(guān)SpringBoot 手機驗證碼登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot配置文件中數(shù)據(jù)庫密碼加密兩種方案(推薦)

    SpringBoot配置文件中數(shù)據(jù)庫密碼加密兩種方案(推薦)

    SpringBoot項目經(jīng)常將連接數(shù)據(jù)庫的密碼明文放在配置文件里,安全性就比較低一些,尤其在一些企業(yè)對安全性要求很高,因此我們就考慮如何對密碼進行加密,文中給大家介紹加密的兩種方式,感興趣的朋友一起看看吧
    2019-10-10
  • Windows?系統(tǒng)上安裝?Kafka的詳細步驟

    Windows?系統(tǒng)上安裝?Kafka的詳細步驟

    本文詳細介紹了在Windows系統(tǒng)上安裝和配置Apache?Kafka的步驟,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Java基礎(chǔ)之容器LinkedList

    Java基礎(chǔ)之容器LinkedList

    這篇文章主要介紹了Java基礎(chǔ)之容器LinkedList,文中有非常詳細的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • java Arrays類詳解及實例代碼

    java Arrays類詳解及實例代碼

    這篇文章主要介紹了java Arrays類詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 詳解Java中的final關(guān)鍵字

    詳解Java中的final關(guān)鍵字

    這篇文章主要給大家介紹了關(guān)于Java中final關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • IDEA 2019.1.3 激活碼大全

    IDEA 2019.1.3 激活碼大全

    本文是小編給大家收藏整理的IDEA 2019.1.3 激活碼大全,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2019-10-10
  • 解決idea web工程修改js文件之后不變化的問題

    解決idea web工程修改js文件之后不變化的問題

    這篇文章主要介紹了解決idea web工程修改js文件之后不變化的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • windows如何使用bat腳本后臺啟動/停止和重啟jar包服務(wù)

    windows如何使用bat腳本后臺啟動/停止和重啟jar包服務(wù)

    這篇文章主要介紹了windows使用bat腳本后臺啟動/停止和重啟jar包服務(wù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java中json與javaBean幾種互轉(zhuǎn)的講解

    Java中json與javaBean幾種互轉(zhuǎn)的講解

    今天小編就為大家分享一篇關(guān)于Java中json與javaBean幾種互轉(zhuǎn)的講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • IDEA下創(chuàng)建SpringBoot+MyBatis+MySql項目實現(xiàn)動態(tài)登錄與注冊功能

    IDEA下創(chuàng)建SpringBoot+MyBatis+MySql項目實現(xiàn)動態(tài)登錄與注冊功能

    這篇文章主要介紹了IDEA下創(chuàng)建SpringBoot+MyBatis+MySql項目實現(xiàn)動態(tài)登錄與注冊功能,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02

最新評論

深州市| 潮安县| 犍为县| 侯马市| 定远县| 灵武市| 威海市| 大英县| 炉霍县| 麻城市| 铜鼓县| 河池市| 同德县| 星座| 阿勒泰市| 嫩江县| 金昌市| 阿拉善左旗| 云龙县| 泸定县| 宁南县| 颍上县| 元朗区| 佛坪县| 图们市| 宜兰县| 葫芦岛市| 惠安县| 丰顺县| 张家界市| 阳信县| 信宜市| 随州市| 陵川县| 墨竹工卡县| 深泽县| 崇礼县| 凌云县| 太湖县| 宁蒗| 瑞金市|