郵箱認證流程

來源:互聯網
上載者:User

標籤:應該   pen   方法   def   如何   images   img   lda   xid   

在日常生活中,我們在一個網站中註冊一個賬戶時,往往在提交個人資訊後,網站還要我們通過手機或郵件來驗證,郵件的話大概會是下面這個樣子的:

  

使用者通過點選連結從而完成註冊,然後才能登入。

也許你會想,為什麼要這麼麻煩直接提交註冊不就行了嗎?這其中很大一部分原因是為了防止惡意註冊。接下來讓我們一起來使用最簡單的JSP+Servlet的方式來完成一個通過郵箱驗證註冊的小案例吧。

準備工作前提知識

動手實踐之前,你最好對以下知識有所瞭解:

  • JSP和Servlet
  • Maven
  • MySQL
  • c3p0
  • SMTP協議和POP3協議

如果對郵件收發過程完全不瞭解的話,可以花三分鐘的時間到慕課網瞭解一下,講得算是非常清楚了,這裡就不贅述了。放張圖回憶一下:

 郵件收發過程郵箱準備

在瞭解的上述內容之後,要實現這個案例,首先我們還得有兩個郵箱帳號,一個用來發送郵件,一個用來內送郵件。本案例使用QQ郵箱向163郵箱發送啟用郵件,因此需要登入QQ郵箱,在設定->賬戶面板中開啟POP3/SMTP服務,以允許我們通過第三方用戶端發送郵件:

  

還要注意的是,登入以下服務: POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務時,需要用到授權碼而不是QQ密碼,授權碼是用於登入第三方郵件用戶端的專用密碼。因此我們需要獲得授權碼,以在後面的程式中使用。

好了,到此準備工作就差不多了,下面開始動手吧。

實現註冊Demo建立Maven工程

本次案例基於Maven,因此你要先建立一個Maven的Web工程,並引入相關依賴:

<dependencies>        <!-- JavaEE依賴 -->        <dependency>            <groupId>javaee</groupId>            <artifactId>javaee-api</artifactId>            <version>5</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>taglibs</groupId>            <artifactId>standard</artifactId>            <version>1.1.2</version>        </dependency>        <!-- mysql驅動依賴 -->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.40</version>        </dependency>        <!-- c3p0依賴 -->        <dependency>            <groupId>c3p0</groupId>            <artifactId>c3p0</artifactId>            <version>0.9.1.2</version>        </dependency>        <!-- JavaMail相關依賴 -->        <dependency>            <groupId>javax.mail</groupId>            <artifactId>mail</artifactId>            <version>1.4.7</version>        </dependency>        <dependency>            <groupId>javax.activation</groupId>            <artifactId>activation</artifactId>            <version>1.1.1</version>        </dependency></dependencies>
建立資料庫表

接下來使用MySQL建立一張簡單的使用者表:

create table `user`(    id int(11) primary key auto_increment comment ‘使用者id‘,    username varchar(255) not null comment ‘使用者名稱‘,    email varchar(255) not null comment ‘使用者郵箱‘,    password varchar(255) not null comment ‘使用者密碼‘,    state int(1) not null default 0 comment ‘使用者啟用狀態:0表示未啟用,1表示啟用‘,    code varchar(255) not null comment ‘啟用碼‘)engine=InnoDB default charset=utf8;

其中要注意的地方是state欄位(用來判斷使用者帳號是否啟用)和code欄位(啟用碼)。

建立註冊頁面

使用JSP建立一個最簡單的註冊頁面(請自行忽略介面):

  

嗯,果然夠簡單。

主要的商務邏輯

先想一下,我們的整個流程應該是這樣的:

  1. 使用者填寫相關資訊,點擊註冊按鈕
  2. 系統先將使用者記錄儲存到資料庫中,其中使用者狀態為未啟用
  3. 系統發送一封郵件並通知使用者去驗證
  4. 使用者登入郵箱並點擊啟用連結
  5. 系統將使用者狀態更改為已啟用並通知使用者註冊成功

搞清楚了整個流程,實現起來應該就不難了。是我建立的包結構:

  

ps:完整代碼請見後文連結,這裡只討論主要的思路

首先是,使用者提交註冊資訊後,相應的servlet會將相關資訊傳給service層去處理,在service中需要做的就是講記錄儲存到資料庫中(調用dao層),然後再給使用者發送一封郵件,UserServiceImpl相關代碼如下:

public boolean doRegister(String userName, String password, String email) {    // 這裡可以驗證各欄位是否為空白        //利用Regex(可改進)驗證郵箱是否符合郵箱的格式    if(!email.matches("^\\[email protected](\\w+\\.)+\\w+$")){        return false;    }    //產生啟用碼    String code=CodeUtil.generateUniqueCode();    User user=new User(userName,email,password,0,code);    //將使用者儲存到資料庫    UserDao userDao=new UserDaoImpl();    //儲存成功則通過線程的方式給使用者發送一封郵件    if(userDao.save(user)>0){        new Thread(new MailUtil(email, code)).start();;        return true;    }    return false;}

需要注意的是,應該建立一個線程去執行發送郵件的任務,不然被罵估計是免不了了。
資料庫的操作比較簡單,此處就不貼出來了,無非是將使用者記錄插到資料庫中。值得一提的是,此處使用c3p0來作為資料來源來替代DriverManager,在頻繁擷取釋放資料庫連接時效率會大大提高,c3p0最簡單的配置如下:

<?xml version="1.0" encoding="UTF-8"?><c3p0-config>    <named-config name="mysql">        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test1?useSSL=false</property>        <property name="user">root</property>        <property name="password">123456</property>        <!-- 初始化時一個串連池嘗試獲得的串連數量,預設是3,大小應該在maxPoolSize和minPoolSize之間 -->        <property name="initialPoolSize">5</property>        <!-- 一個串連最大空閑時間(單位是秒),0意味著串連不會過時 -->        <property name="maxIdleTime">30</property>        <!-- 任何指定時間的最大串連數量 ,預設值是15 -->        <property name="maxPoolSize">20</property>        <!-- 任何指定時間的最小串連數量 ,預設值是3 -->        <property name="minPoolSize">5</property>    </named-config></c3p0-config> 

提供一個工具類DBUtil以擷取,釋放串連:

<pre>
public class DBUtil {
private static ComboPooledDataSource cpds=null;

static{    cpds=new ComboPooledDataSource("mysql");}public static Connection getConnection(){    Connection connection=null;    try {        connection = cpds.getConnection();    } catch (SQLException e) {        e.printStackTrace();    }    return connection;}public static void close(Connection conn,PreparedStatement pstmt,ResultSet rs){    try {        if(rs!=null){            rs.close();        }        if(pstmt!=null){            pstmt.close();        }        if(rs!=null){            rs.close();        }    } catch (SQLException e) {        e.printStackTrace();    }    }

}
</pre>

要特別注意的一點是:即使是使用串連池,使用完Connection後調用close方法,當然這不意味著關閉與資料庫的TCP 串連,而是將串連還回到池中去,如果不close掉的話,這個串連將會一直被佔用,直到串連池中的串連耗盡為止。

使用JavaMail發送郵件

使用JavaMail發送郵件非常簡單,也是三步曲:

  1. 建立連線物件javax.mail.Session
  2. 建立郵件對象 javax.mail.Message
  3. 發送郵件

直接看代碼,詳細的注釋在代碼中,MailUtil代碼如下:

    public class MailUtil implements Runnable {    private String email;// 收件者郵箱    private String code;// 啟用碼    public MailUtil(String email, String code) {        this.email = email;        this.code = code;    }    public void run() {        // 1.建立連線物件javax.mail.Session        // 2.建立郵件對象 javax.mail.Message        // 3.發送一封啟用郵件        String from = "[email protected]";// 寄件者電子郵箱        String host = "smtp.qq.com"; // 指定發送郵件的主機smtp.qq.com(QQ)|smtp.163.com(網易)        Properties properties = System.getProperties();// 擷取系統屬性        properties.setProperty("mail.smtp.host", host);// 設定郵件伺服器        properties.setProperty("mail.smtp.auth", "true");// 開啟認證        try {            //QQ郵箱需要下面這段代碼,163郵箱不需要            MailSSLSocketFactory sf = new MailSSLSocketFactory();            sf.setTrustAllHosts(true);            properties.put("mail.smtp.ssl.enable", "true");            properties.put("mail.smtp.ssl.socketFactory", sf);            // 1.擷取預設session對象            Session session = Session.getDefaultInstance(properties, new Authenticator() {                public PasswordAuthentication getPasswordAuthentication() {                    return new PasswordAuthentication("[email protected]", "xxx"); // 寄件者郵箱帳號、授權碼                }            });            // 2.建立郵件對象            Message message = new MimeMessage(session);            // 2.1設定寄件者            message.setFrom(new InternetAddress(from));            // 2.2設定接收人            message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));            // 2.3設定郵件主題            message.setSubject("帳號啟用");            // 2.4設定郵件內容            String content = "<html><head></head><body><h1>這是一封啟用郵件,啟用請點擊以下連結</h1><h3><a href=‘http://localhost:8080/RegisterDemo/ActiveServlet?code="                    + code + "‘>http://localhost:8080/RegisterDemo/ActiveServlet?code=" + code                    + "</href></h3></body></html>";            message.setContent(content, "text/html;charset=UTF-8");            // 3.發送郵件            Transport.send(message);            System.out.println("郵件成功發送!");        } catch (Exception e) {            e.printStackTrace();        }    }}

ps:需要把上面的帳號、授權碼進行相應修改。

完成後,再有使用者提交註冊資訊時,應該就能收到驗證郵件了:

  

使用者點選連結後,我們要做的工作就是根據code(可以利用UUID產生)更改資料庫中相應使用者的狀態,然後提示使用者註冊結果了。

總結

簡單介紹了如何使用JavaMail完成了一個帶郵箱驗證的註冊案例,當然在實際開發中還有許多細節要注意,例如對使用者提交資訊的校正,密碼進行加密等,此處的簡單案例並未詳盡處理這些細節。

代碼

SnDragon
連結:https://www.jianshu.com/p/8f8d7a46888f
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

郵箱認證流程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.