欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、短信發(fā)送

1.1 阿里云短信服務

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

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

1.1.1 設置短信簽名

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

1.1.2 模板管理

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

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

1.1.3 設置AccessKey

創(chuàng)建新的用戶

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

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

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

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

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

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

參照官方文檔即可

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

1.2.1 導入maven坐標

        <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);
//      我們在阿里云設置的簽名
		request.setSignName(signName);
//	    我們在阿里云設置的模板
		request.setTemplateCode(templateCode);
//	    在設置模板的時候有一個占位符
		request.setTemplateParam("{\"code\":\""+param+"\"}");
//		request.setPhoneNumbers("1368846****");//接收短信的手機號碼
//		request.setSignName("阿里云");//短信簽名名稱
//		request.setTemplateCode("SMS_20933****");//短信模板CODE
//		request.setTemplateParam("張三");//短信模板變量對應的實際值
		try {
			SendSmsResponse response = client.getAcsResponse(request);
			System.out.println("短信發(fā)送成功");
		}catch (ClientException e) {
			e.printStackTrace();
		}
	}
}

1.3  手機驗證碼登錄

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

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

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

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

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

1.3.2  修改過濾器

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

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

 
/**
 * 檢查用戶是否已經(jīng)完成登錄
 * 過濾器與攔截器的區(qū)別:Filter對所有訪問進行增強(在Tomcat服務器進行配置),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"));
//           通過輸出流的方式向客戶端響應數(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請求,在服務端調(diào)用短信服務API給指定手機號發(fā)送驗證碼短信

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

    @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)用阿里云提供的短信服務
        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("登錄失敗");
    }

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

相關文章

  • SpringBoot項目jar和war打包部署方式詳解

    SpringBoot項目jar和war打包部署方式詳解

    這篇文章主要為大家介紹了SpringBoot項目jar和war打包部署方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • java遞歸處理單位人員組織機構樹方式

    java遞歸處理單位人員組織機構樹方式

    這篇文章主要介紹了java遞歸處理單位人員組織機構樹方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • JVM內(nèi)存結(jié)構劃分實例解析

    JVM內(nèi)存結(jié)構劃分實例解析

    這篇文章主要介紹了JVM內(nèi)存結(jié)構劃分實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • OpenTelemetry?Java?SDK?高級用法解析

    OpenTelemetry?Java?SDK?高級用法解析

    這篇文章主要介紹了OpenTelemetry?Java?SDK?的高級用法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • java生成圖片驗證碼返回base64圖片信息方式

    java生成圖片驗證碼返回base64圖片信息方式

    這篇文章主要介紹了java生成圖片驗證碼返回base64圖片信息方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Java使用BouncyCastle加密

    Java使用BouncyCastle加密

    本文主要介紹了Java使用BouncyCastle加密,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • 解讀synchronized鎖的釋放機制

    解讀synchronized鎖的釋放機制

    這篇文章主要介紹了synchronized鎖的釋放機制,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • MyBatisPlus-QueryWrapper多條件查詢及修改方式

    MyBatisPlus-QueryWrapper多條件查詢及修改方式

    這篇文章主要介紹了MyBatisPlus-QueryWrapper多條件查詢及修改方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Springboot2集成pagehelper過程圖解

    Springboot2集成pagehelper過程圖解

    這篇文章主要介紹了springboot2集成pagehelper過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • PropertiesLoaderUtils 出現(xiàn)中文亂碼的解決方式

    PropertiesLoaderUtils 出現(xiàn)中文亂碼的解決方式

    這篇文章主要介紹了PropertiesLoaderUtils 出現(xiàn)中文亂碼的解決方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08

最新評論