node.js郵箱註冊,啟用,登陸相關案例

wangweifeng發表於2019-02-16

email-verify

具體的詳細程式碼github
現在的登陸系統除了第三方登陸接入以外,主要有簡訊登陸和郵箱登陸,按照現在實名制的特點,現在的簡訊登陸比較多,但是還是有一些會用到郵箱登陸的。
本文主要是關於郵箱登陸的相關案例,通俗的說就是使用者使用郵箱註冊,當註冊成功時,會給註冊使用者發郵件進行啟用,當然這個郵件有一定的時效性。當使用者啟用後可以正常使用相關的功能,沒啟用,當登陸時會提示沒啟用,是否需要在傳送一條郵件啟用。

1. 使用工具

  • node v8.5.0
  • mongodb
  • ioredis
  • postman

2. 專案結構

專案結構圖
專案結構圖

圖中說明了關鍵檔案的含義

3. 使用者註冊介面

當使用者註冊時,首先檢查必要欄位是否傳入以及郵箱密碼是否符合規範,然後檢查郵箱是否已註冊,當註冊成功時會傳送一個郵件給使用者用來啟用這個賬號,這個傳送的郵件內容為一個連結,包含了這個使用者的郵箱以及code,code使用reids設定了過期時間。(未啟用時使用者狀態為0,啟用狀態為1)
路由routes中註冊路由如下:

 //user_regist
router.post('/user_regist', userCtrl.user_regist);複製程式碼

controllers中註冊的部分程式碼如下:

     try {
        const user = await findUserAsyc({ 'useremail': user_email });//驗證使用者是否已註冊
        if (user) {
            respondData.status = 10002;
            respondData.error = "郵箱已註冊";
            return res.json(respondData);
        }
        //使用者引數
        const userpassword = md5(user_password);
        const userInfo = {
            useremail: user_email,
            username: user_name,
            userpwd: userpassword,
            status: 0,
            create_time: Date.now('YYYY-MM-DD')
        };
        //新建使用者
        console.log("newGuess.save userInfo-->" + JSON.stringify(userInfo));
        const newUser = new UserModel(userInfo);
        newUser.save(function (err, data) {
            if (err) {
                console.log("newGuess.save err-->" + JSON.stringify(err));
                respondData.status = "00001";
                respondData.error = "mongodb system error";
                return res.json(respondData);
            }
            console.log("newGuess.save data -->" + JSON.stringify(data));
            let userEmail = data.useremail;
            let sendEmail = sendUserEmail(userEmail);
            console.log("sendEmail:" + sendEmail);
            respondData.msg = "新使用者註冊成功 and 啟用郵箱傳送成功";
            return res.json(respondData);
        });
    } catch (error) {
        //錯誤處理
        console.log("controllers/UserController.js/user_regist error -->" + JSON.stringify(error));
        respondData.error = error;
        return res.json(respondData);
    }複製程式碼

郵箱傳送部分程式碼

    var config_email = {
        host: 'smtp.163.com',
        post: 25, // SMTP 埠
        //secureConnection: true, // 使用 SSL
        auth: {
            user: 'wangweifengyx@163.com',
            //這裡密碼不是qq密碼,是你設定的smtp密碼
            pass: 'wwf'
        }
    };
    var transporter = nodemailer.createTransport(config_email);

    var html = "<div>http://127.0.0.1:3000?code=" + code + "&account=" + cnd + "</div>";
    console.log(html);
    var data = {
        from: 'wangweifengyx@163.com', // 發件地址
        to: cnd, // 收件列表
        subject: 'Hello feng', // 標題

        //text: html // 標題 //text和html兩者只支援一種
        html: html // html 內容
    };
    console.log(data);
    transporter.sendMail(data, function (err, info) {
        if (err) {
            return (err);
        }
        console.log(info.response);
        return (info.response);

    });複製程式碼

使用postman模擬註冊

postman模擬註冊
postman模擬註冊

此時的截圖正好把傳送郵箱的訊息也擷取了,完美

使用者沒有啟用時資料庫中這條使用者的status=0;如圖:
資料庫使用者資訊

資料庫使用者資訊
資料庫使用者資訊

4. 使用者郵箱啟用

通過點選郵箱中的連結會啟用郵箱,當郵箱和code不匹配時,會返回郵箱不匹配訊息,當code過期時,會返回code過期訊息,當使用者已啟用時,會告訴已啟用,不要重複啟用,當使用者資訊無上述的幾種情況時會,提示啟用成功。
路由routes中啟用路由如下:

//user_activation
router.get('/user_activation', userCtrl.user_activation);複製程式碼

controllers中註冊的部分程式碼如下:

    try {
        let codeVal = await Jtoken(code);
        if (!codeVal) {
            respondData.error = "code失效,請重新傳送郵件啟用";
            return res.json(respondData);
        }
        let userinfo = JSON.parse(codeVal);
        if (userinfo.userEmail !== user_email) {
            respondData.error = "郵箱不正確";
            return res.json(respondData);
        }
        const user = await findUserAsyc({ 'useremail': user_email });//驗證使用者是否已註冊
        if (user) {
            if (user.status === 0) {
                UserModel.update({ 'useremail': user_email }, { '$set': { status: 1 } }, function (err, results) {
                    if (err) {
                        console.log("UserModel.update err-->" + JSON.stringify(err));
                        respondData.status = "00001";
                        respondData.error = "mongodb system error";
                        return res.json(respondData);
                    }
                    respondData.msg = "郵箱啟用成功";
                    return res.json(respondData);
                })
            } else if (user.status === 1) {
                respondData.msg = "此郵箱已經啟用了哦,不要重複啟用";
                return res.json(respondData);
            }
        }
    } catch (error) {
        //錯誤處理
        console.log("controllers/UserController.js/user_regist error -->" + JSON.stringify(error));
        respondData.error = error;
        return res.json(respondData);
    }複製程式碼

使用postman模擬啟用成功

postman模擬啟用成功
postman模擬啟用成功

使用postman模擬啟用code失效
postman模擬啟用code失效
postman模擬啟用code失效

啟用成功時資料庫的使用者資訊
啟用成功時資料庫的使用者資訊
啟用成功時資料庫的使用者資訊

5. 使用者登陸介面

當使用者未啟用時,登陸會告知未啟用,需要去啟用,當已啟用時資訊正常時會成功登陸,當成功登陸時會返回使用者的一些資訊以及加一個token。
路由routes中登陸路由如下:

//user_login
router.post('/user_login', userCtrl.user_login);複製程式碼

controllers中登陸的部分程式碼如下:

    try {
        const user = await findUserAsyc({ 'useremail': user_email });//驗證使用者是否已註冊
        if (!user) {
            respondData.status = 10000;
            respondData.error = "郵箱未註冊";
            return res.json(respondData);
        }
        const userverify = await findUserVerify(user_email,user_password);//驗證使用者
        if(!userverify){
            respondData.status = 10005;
            respondData.error = "郵箱或密碼錯誤";
            return res.json(respondData);
        }
        console.log(userverify);
        if(userverify.status === 0){
            respondData.status = 10006;
            respondData.error = "郵箱未啟用,請啟用郵箱";
            return res.json(respondData);
        } else if(userverify.status === 1){
            const tokenexpiraton = 1800;
            const token = require('crypto').randomBytes(16).toString('hex');
            const tokenContent = {
                useremail: userverify.useremail,
                username: userverify.username
            };
            redis.set(token, JSON.stringify(tokenContent));
            redis.expire(token, tokenexpiraton);
            const userBackInfo = {};
            userBackInfo.token = token;
            userBackInfo.useremail = userverify.useremail;
            userBackInfo.username = userverify.username;
            userBackInfo._id = userverify._id;
            respondData.data.push(userBackInfo);
            respondData.msg = "登陸成功";
            return res.json(respondData);
        }    
    } catch (error) {
        //錯誤處理
        console.log("controllers/UserController.js/user_regist error -->" + JSON.stringify(error));
        respondData.error = error;
        return res.json(respondDaata);
    }複製程式碼

未啟用登陸時

未啟用登陸時
未啟用登陸時

已啟用登陸時
已啟用登陸時
已啟用登陸時

6. 後續

目前來說只有註冊,啟用,登陸介面,後續也可以實現更多的功能,同時還沒有測試,其實也可以加上測試的。

相關文章