Skip to content

wang-weifeng/email-verify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

email-verify

现在的登陆系统除了第三方登陆接入以外,主要有短信登陆和邮箱登陆,按照现在实名制的特点,现在的短信登陆比较多,但是还是有一些会用到邮箱登陆的。 本文主要是关于邮箱登陆的相关案例,通俗的说就是用户使用邮箱注册,当注册成功时,会给注册用户发邮件进行激活,当然这个邮件有一定的时效性。当用户激活后可以正常使用相关的功能,没激活,当登陆时会提示没激活,是否需要在发送一条邮件激活。

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: '[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模拟注册 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模拟激活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. 后续

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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published