索鸟网

  1. 首页
  2. node.js邮箱注册,激活,登陆相关案例

node.js邮箱注册,激活,登陆相关案例


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模拟注册

此时的截图正好把发送邮箱的消息也截取了,完美

用户没有激活时数据库中这条用户的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模拟激活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. 后续

目前来说只有注册,激活,登陆接口,后续也可以实现更多的功能,同时还没有测试,其实也可以加上测试的。

node.js mongodb redis

来源地址:https://segmentfault.com/a/1190000011409797 版权归作者所有!