
具体的详细代码 github 现在的登陆系统除了第三方登陆接入以外,主要有短信登陆和邮箱登陆,按照现在实名制的特点,现在的短信登陆比较多,但是还是有一些会用到邮箱登陆的。 本文主要是关于邮箱登陆的相关案例,通俗的说就是用户使用邮箱注册,当注册成功时,会给注册用户发邮件进行激活,当然这个邮件有一定的时效性。当用户激活后可以正常使用相关的功能,没激活,当登陆时会提示没激活,是否需要在发送一条邮件激活。
- node v8.5.0
- mongodb
- ioredis
- postman
图中说明了关键文件的含义
当用户注册时,首先检查必要字段是否传入以及邮箱密码是否符合规范,然后检查邮箱是否已注册,当注册成功时会发送一个邮件给用户用来激活这个账号,这个发送的邮件内容为一个链接,包含了这个用户的邮箱以及 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: '[email protected]', //这里密码不是 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: '[email protected]', // 发件地址 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 ;如图: 数据库用户信息
通过点击邮箱中的链接会激活邮箱,当邮箱和 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 失效
激活成功时数据库的用户信息
当用户未激活时,登陆会告知未激活,需要去激活,当已激活时信息正常时会成功登陆,当成功登陆时会返回用户的一些信息以及加一个 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); } 未激活登陆时 已激活登时
目前来说只有注册,激活,登陆接口,后续也可以实现更多的功能,同时还没有测试,其实也可以加上测试的。