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