項目優化方案之---實現郵箱用戶登錄

之前的項目中我寫的基于SpringBoot和Vue的全棧項目已經實現了基本的用戶接口開發,

不過其代碼的功能單一,而且寫的也是有不少漏洞(基本就像剛接手的代碼*山一樣)

那之后的幾篇文章都來分享一下如何優化項目(每一章都獨立講方案,不必看之前的)

這里來添加一種登錄方法,用郵箱來登錄(實際思路跟手機號登錄是差不多的,而且都是要借助一些第三方的工具實現)

操作之前先來梳理一下實現流程:

1.用戶填寫其郵箱(這里我只用QQ郵箱實現)

2.點擊發送驗證碼按鈕(ok,此處需要發送請求到后端進行一系列操作Todo)

3.獲取到了驗證碼,填寫驗證碼,并點擊登錄按鈕(這里又要調用一次接口檢驗驗證碼是否正確)

總結一下后端要做的接口有哪些:

1.接收qq郵箱并生成驗證碼發送請求

? ? ? ?(具體實現:1.校驗QQ郵箱是否格式正確(這里用SpringValildation即可),2.生成驗證碼,并將其保存到(??),這里其實有很多種方案可供選擇,比如放到session,這里的話我用ThreadUtils操作一下,(后續統一用Redis操作),然后使用第三方工具把驗證碼發送到對應的QQ郵箱就可以了)

2.接收用戶的驗證碼和其QQ郵箱號,進行二次校驗,驗證驗證碼與生成的驗證碼是否相等,如果相等就可以根據QQ郵箱去查找是否有這個人(這里可以拓展一下,如果沒有這個人就可以直接幫他注冊),這里沒有這個人就返回沒有這個用戶并讓其去注冊的消息,如果有這個人就按照正常流程登錄即可,(這里我的登錄用的是JWT令牌,如果登錄成功還要返回令牌給前端)

Ok,開始后端接口開發:

1.定義DTO

先確認一下之前定義的User實體類中要有email屬性啊

    @Email@NotEmpty(message = "郵箱不能為空")private String email;

這里在User實體類這里記得要加上email郵箱屬性(這里還有兩個注釋)

我這里用到了SpringValidation進行參數校驗,(也就是這兩個注解),不知道的同志可以看看之前的文章或者上網搜一下。

OK,這里就可以定義一個接收的實體類了,

由于兩個接口一個接收QQ郵箱,一個接收QQ郵箱+驗證碼,因此這一個DTO也就足夠了(如果愿意,也可以用User,不過我這個User定義的屬性似乎有點多,感覺會很麻煩)

package org.example.cetidenet.model.dto.user;import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;public class UserEmailDTO {@Email@NotEmpty(message = "郵箱不能為空")private String email;private String code;public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}@Overridepublic String toString() {return "UserEmailDTO{" +"email='" + email + '\'' +", code='" + code + '\'' +'}';}
}

2.開發發送驗證碼的接口

在Controller類這里我們新定義一個方法

    @PostMapping("/submitEmail")public Result<User> submitEmail(@RequestBody @Validated UserEmailDTO userEmailDTO) {return userService.submitEmail(userEmailDTO);}

這里由于已經使用了@Validated來進行參數校驗了,那我們直接返回userService的方法就好,盡量把邏輯處理的函數都放到Service的實現類中。

既然郵箱的格式已經正確了就生成一串隨機數字吧

這里就使用RandomUtil生成

String code = RandomUtil.randomNumbers(6);

這樣就生成了一個6位的隨機數字;

既然萬事俱備,那么就該發送驗證碼了,

3.講解QQ郵箱發送驗證碼:
?

這里我使用JavaMail發送驗證碼,來看看使用方法:
?

步驟1.獲取QQ郵箱授權碼:

點開QQ郵箱,左上角有設置,點擊設置

再點擊賬號

往下翻,點擊開啟服務即可

然后通過驗證即可獲取到授權碼,(記得保存好)

步驟2:在后端工程中引入依賴
<dependency><groupId>javax.mail</groupId><artifactId>mail</artifactId><version>1.4</version>
</dependency>
步驟3:按照代碼填充:
import java.security.Security;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;public class MailClient {public static void main(String[] args) {try {final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";//配置郵箱信息Properties props = System.getProperties();//郵件服務器props.setProperty("mail.smtp.host", "smtp.qq.com");props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);props.setProperty("mail.smtp.socketFactory.fallback", "false");//郵件服務器端口props.setProperty("mail.smtp.port", "465");props.setProperty("mail.smtp.socketFactory.port", "465");//鑒權信息props.setProperty("mail.smtp.auth", "true");//建立郵件會話Session session = Session.getDefaultInstance(props, new Authenticator() {//身份認證protected PasswordAuthentication getPasswordAuthentication() {//1.賬戶 授權碼return new PasswordAuthentication("xxxxxxx@qq.com", "xxxx");}});//建立郵件對象MimeMessage message = new MimeMessage(session);//設置郵件的發件人message.setFrom(new InternetAddress("xxxxxxx@qq.com"));//2.設置郵件的收件人message.setRecipients(Message.RecipientType.TO, "xxxxxxx@qq.com");//設置郵件的主題message.setSubject("通過javamail發出!!!");//文本部分message.setContent("文本郵件測試", "text/html;charset=UTF-8");message.saveChanges();//發送郵件Transport.send(message);} catch (Exception e) {e.printStackTrace();}}
}

此處將? ? ? ? ? return new PasswordAuthentication("xxxxxxx@qq.com", "xxxx");

填充為你的賬號和授權碼,

下面的發件人填寫你的郵箱(不要填別人的,不然要報錯的)

收件人的郵箱填Controller類處接收到的代碼即可;

下面來具體實現一下:

這個郵箱發送代碼較長,這邊可以將其封裝為一個工具類或者函數(我感覺這種要長不長,要短不短的封裝成函數比較合適)

那就來展示一下UserServiceImpl的這個方法調用吧;

@Overridepublic Result<User> submitEmail(UserEmailDTO userEmailDTO) {String email = userEmailDTO.getEmail();String code = RandomUtil.randomNumbers(6);sendEmail(email,code);ThreadLocalUtil.set(code);return Result.success();}private static void sendEmail(String email,String code){try {final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";//配置郵箱信息Properties props = System.getProperties();//郵件服務器props.setProperty("mail.smtp.host", "smtp.qq.com");props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);props.setProperty("mail.smtp.socketFactory.fallback", "false");//郵件服務器端口props.setProperty("mail.smtp.port", "465");props.setProperty("mail.smtp.socketFactory.port", "465");//鑒權信息props.setProperty("mail.smtp.auth", "true");//建立郵件會話Session session = Session.getDefaultInstance(props, new Authenticator() {//身份認證protected PasswordAuthentication getPasswordAuthentication() {//1.賬戶 授權碼return new PasswordAuthentication("1147683258@qq.com", "bsfyppqvhrqqecgj");}});//建立郵件對象MimeMessage message = new MimeMessage(session);//設置郵件的發件人message.setFrom(new InternetAddress("1147683258@qq.com"));//2.設置郵件的收件人message.setRecipients(Message.RecipientType.TO, email);//設置郵件的主題message.setSubject("來自Cetide網的信息");//文本部分message.setContent("收到您的登錄請求發送驗證碼"+code, "text/html;charset=UTF-8");message.saveChanges();//發送郵件Transport.send(message);} catch (Exception e) {e.printStackTrace();}}

Ok,那么這個接口也就開發的差不多了,這里來驗證一下吧,啟動SpringBoot項目并打開Swagger試試

輸入一個QQ小號的地址即可發送出驗證碼

那么,這也就發送成功了。(這里我測試的時候,感覺請求發出過程好慢,可以看看有沒有更快速一些的QQ郵箱調用)

后續的登錄就比較簡單了,這里添加一個登錄接口

這邊也就不細致講解了,直接上代碼,大家觀看吧

    @PostMapping("/email/submit")public Result login(@RequestBody @Validated UserEmailDTO userEmailDTO){// 實現登錄功能return userService.emailLogin(userEmailDTO);}
    @Overridepublic Result emailLogin(UserEmailDTO userEmailDTO) {String email = userEmailDTO.getEmail();String userCode = userEmailDTO.getCode();String code = ThreadLocalUtil.get();if(!code.equals(userCode)){return Result.error("驗證碼錯誤");}//現在說明這個驗證碼正確User user = userMapper.findByEmail(email);if(user == null){return Result.error("該郵箱未注冊用戶,請先注冊");}//存在該用戶Map<String, Object> claims = new HashMap<>();claims.put("id", user.getId());claims.put("username", user.getUserName());String token = JwtUtil.genToken(claims);//存在且密碼正確return Result.success(token);}
    @Select("select * from user where  email = #{email}")User findByEmail(String email);

此處代碼也就差不多能夠實現根據QQ郵箱登錄的功能了;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/21897.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/21897.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/21897.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python優化、異常處理與性能提升技巧

Python作為一種高效的編程語言&#xff0c;其靈活性和強大的功能使得它成為了許多開發者的首選。在日常的編程實踐中&#xff0c;掌握一些高效的Python技巧可以極大地提升開發效率和代碼質量。本文將介紹五個關于Python使用技巧&#xff0c;幫助你更加熟練地運用Python解決問題…

JMeter性能測試實現與分析分享

JMeter是由著名開源軟件巨頭Apache組織開發的純Java的壓力測試工具&#xff0c;它即能測試動態服務&#xff08;WebService&#xff09;&#xff0c;也能測試靜態資源&#xff0c;包括Servlet服務、CGI腳本等&#xff0c;還能測試動態語言服務&#xff08;PHP、Java、ASP.NET等…

Cocos Creator開發學習路線

1.JavaScript與TypeScript程序設計 由于可以跨平臺發布,同時要能支持h5的游戲,cocos creator選擇了JavaScript與TypeScript來做為它的開發語言,所以我們要先學習JavaScript與TypeScript。TypeScript是基于JavaScript的一個語法糖,運行的時候被編譯為JavaScript,所以我們要…

JVM學習-監控工具(二)

jmap&#xff1a;導出內存映像文件&內存使用情況 基本情況 jmap(JVM Memory Map)&#xff1a;一方法獲取dump文件(堆轉儲快照文件&#xff0c;二進制文件)&#xff0c;還可以獲取目標Java進程的內存相關信息&#xff0c;包括Java堆各區域的使用情況、堆中對象的統計信息、…

MyBatis學習(二)--MyBatis獲取參數值的兩種方式

1、搭建新的module:mybatis_parameter MyBatis獲取參數值的兩種方式&#xff1a;${}和#{} ${}的本質就是字符串拼接&#xff0c;采用sql拼接&#xff0c;無法防止sql注入 #{}的本質就是占位符賦值 &#xff0c;采用預編譯 防止sql注入 不同參數使用案例 2、單個字面量類型…

OpenHarmony嵌套類對象屬性變化:@Observed裝飾器和@ObjectLink裝飾器

上文所述的裝飾器僅能觀察到第一層的變化&#xff0c;但是在實際應用開發中&#xff0c;應用會根據開發需要&#xff0c;封裝自己的數據模型。對于多層嵌套的情況&#xff0c;比如二維數組&#xff0c;或者數組項class&#xff0c;或者class的屬性是class&#xff0c;他們的第二…

實時瞳孔分割算法-RITnet論文復現

源代碼在這里RITnet-Github 這個模型比較小眾&#xff0c;我們實驗室使用了官方提供的模型進行瞳孔中心位置提取&#xff0c;以實現視線追蹤&#xff0c;效果很好 一、數據集準備 RITnet也是那一屆openEDS數據集挑戰賽的冠軍模型&#xff0c;openEDS數據集可以從Kaggle上下載&a…

數據結構--關鍵路徑

事件v1-表示整個工程開始&#xff08;源點&#xff1a;入度為0的頂點&#xff09; 事件v9-表示整個工程結束&#xff08;匯點&#xff1a;出度為0的頂點&#xff09; 關鍵路徑&#xff1a;路徑長度最長的路徑 求解關鍵路徑問題&#xff08;AOE網&#xff09; 定義四個描述量 …

網絡網絡層之(6)ICMPv4協議

網絡網絡層之(6)ICMPv4協議 Author: Once Day Date: 2024年6月2日 一位熱衷于Linux學習和開發的菜鳥&#xff0c;試圖譜寫一場冒險之旅&#xff0c;也許終點只是一場白日夢… 漫漫長路&#xff0c;有人對你微笑過嘛… 全系列文章可參考專欄: 通信網絡技術_Once-Day的博客-CS…

華為OD刷題C卷 - 每日刷題 7(字符串分隔(二)、歡樂的周末)

兩段代碼分別解決了兩個不同的問題&#xff0c;下面是對它們的概述&#xff1a; 1、&#xff08;字符串分隔&#xff08;二&#xff09;&#xff09;&#xff1a; 這段代碼是解決“字符串分隔&#xff08;二&#xff09;”的問題。它提供了一個Java類Main&#xff0c;其中包含…

Java面試題-Tomcat高級面試題

Tomcat 9相較于之前的版本有哪些主要的新特性&#xff1f; Tomcat 9相較于之前的版本&#xff0c;主要有以下幾個新特性&#xff1a; HTTP/2支持&#xff1a;Tomcat 9引入了對HTTP/2協議的支持&#xff0c;這可以顯著提高網站的性能和安全性。HTTP/2協議允許單個連接上進行多…

多語言for循環遍歷總結

多語言for循環遍歷總結 工作中經常需要遍歷對象&#xff0c;但不同編程語言之間存在一些細微差別。為了便于比較和參考&#xff0c;這里對一些常用的遍歷方法進行了總結。 JAVA 數組遍歷 Test void ArrayForTest() {String[] array {"劉備","關羽", &…

大模型備案項目補貼政策一覽【保持更新】

大模型項目、AI類項目、大模型備案通過后等一籃子財政補貼政策 上海市 加快創新體系構建 1. 提升自主創新水平&#xff1a;對引領大模型發展或取得顛覆性突破的項目&#xff0c;最高給予1000萬元補貼支持。 2. 加強算力資源保障&#xff1a;實施算力伙伴計劃&#xff0c;對…

力扣174題動態規劃:地下城游戲(含模擬面試)

?????? 歡迎來到我的博客。希望您能在這里找到既有價值又有趣的內容&#xff0c;和我一起探索、學習和成長。歡迎評論區暢所欲言、享受知識的樂趣&#xff01; 推薦&#xff1a;數據分析螺絲釘的首頁 關注微信公眾號 數據分析螺絲釘 免費領取價值萬元的python/java/商業…

Java進階學習筆記36——算法

什么是算法&#xff1f; 解決某個實際問題的過程和方法。 1&#xff09;導航&#xff1b; 2&#xff09;滴滴打車&#xff1b; 3&#xff09;抖音&#xff1b; 不同的算法&#xff0c;效率高、性能好&#xff01; 在Java中&#xff0c;代碼已經幫我們寫好了&#xff0c;但為…

雪花算法詳解及源碼分析

雪花算法的簡介&#xff1a; 雪花算法用來實現全局唯一ID的業務主鍵&#xff0c;解決分庫分表之后主鍵的唯一性問題&#xff0c;所以就單從全局唯一性來說&#xff0c;其實有很多的解決方法&#xff0c;比如說UUID、數據庫的全局表的自增ID 但是在實際的開發過程中&#xff0…

離散點云擬合三維平面參數推導(基于最小二乘)

1、背景介紹 實際中&#xff0c;很多人工構造物是由平面結構構造而成&#xff0c;如下圖所示&#xff0c;為一典型的由多個平面組成的人工構筑物。因此&#xff0c;根據離散點擬合成平面&#xff0c;獲取擬合平面方程&#xff0c;是點云數據處理中非常常見的數據處理操作。 2、…

鴻蒙Ability Kit(程序框架服務)【ExtensionAbility組件】

ExtensionAbility組件 ExtensionAbility組件是基于特定場景&#xff08;例如服務卡片、輸入法等&#xff09;提供的應用組件&#xff0c;以便滿足更多的使用場景。 每一個具體場景對應一個[ExtensionAbilityType]&#xff0c;開發者只能使用&#xff08;包括實現和訪問&#…

WPS的excel表格設置了編輯權限,要怎么取消?

在日常生活和工作中&#xff0c;我們經常會使用WPS Office辦公軟件來處理各種文檔&#xff0c;其中WPS Excel表格是我們進行數據處理和分析的重要工具。為了保護表格中的數據不被隨意修改&#xff0c;我們有時會設置編輯權限。然而&#xff0c;隨著時間的推移或需求的變更&…

基于FPGA的SystemVerilog練習

文章目錄 一、認識SystemVerilogSystemVerilog的語言特性SystemVerilog的應用領域SystemVerilog的優勢SystemVerilog的未來發展方向 二、流水燈代碼流水燈部分testbench仿真文件 三、用systemVerilog實現超聲波測距計時器測距部分led部分數碼管部分采樣部分頂層文件引腳綁定效果…