Express應用的結構其實就是R(路由)+M(模型)+V(視圖)+C(控制器)。前端
今天總結以前寫的cnode的登錄註冊功能。node
前提搭好環境, mongodb + redis。git
var express = require('express');
var router = express.Router();
//引入控制器
var signController = require('../controller/sign');
// 註冊頁面
router.get('/signup', signController.showSignUp);
// 登錄頁面
router.get('/signin', signController.showSignin);
// 提交註冊
router.post('/signup', signController.signup);
// 提交登錄
router.post('/signin', signController.signin);
// 登出
router.get('/signout', signController.signout);
module.exports = router;複製代碼
// user model
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
// 鏈接本地數據庫
mongoose.connect('mongodb://127.0.0.1/cnode');
// 建立Schema
var UserSchema = new Schema({
username: String,
pass: String,
email: String
});
// 爲model添加方法
// getUserBySignupInfo: 根據註冊信息查詢用戶信息
UserSchema.statics.getUserBySignupInfo = function(username, email, callback){
// 查詢條件
var cond = ['$or', {username: username}, {email: email}];
this.find(cond, callback);
};
// addUser: 添加用戶
UserSchema.statics.addUser = function(user, callback){
// add user
this.create(user, callback);
};
// getUser: 獲取用戶
UserSchema.statics.getUser = function(username, pass, callback){
this.findOne({username: username, pass: pass}, callback);
};
// 根據Schema導出數據模型
module.exports = mongoose.model('User', UserSchema);複製代碼
模板代碼就不貼了, 主要有一點注意.前端如何判斷是否登錄,進行不一樣模板渲染 github
// app.js
// 中間件: 是否用戶登錄
app.use(function(req, res, next){
app.locals.current_user = req.session.user;
next();
});複製代碼
<% if(typeof(current_user) != 'undefined' && success){%>
<li><a href="/signout">登出</a></li>
<% } else {%>
<li><a href="/signup">註冊</a></li>
<li><a href="/signin">登錄</a></li>複製代碼
// 控制器: 處理登錄與註冊邏輯
var eventproxy = require('eventproxy');
// 引入user model
var UserModel = require('../model/user');
// 渲染註冊頁面
exports.showSignUp = function (req, res) {
res.render('sign/signup');
};
// 提交註冊信息
exports.signup = function (req, res) {
// 獲取表單數據
var username = req.body.loginname;
var pass = req.body.pass;
var re_pass = req.body.re_pass;
var email = req.body.email;
var ep = new eventproxy();
// watch emit event
ep.on('info_error', function (msg) {
res.status(422);
res.render('sign/signup', {
error: msg
});
});
// 校驗表單數據
// 空校驗
let userInfoArr = [username, pass, re_pass, email]
for (let i = 0, len = userInfoArr.length; i < len; i++) {
if (userInfoArr[i] === '') {
let msgErr = userInfoArr[i]
ep.emit('info_error', '表單字段內容不能爲空'); // emit錯誤事件
break
return;
}
};
// 密碼確認校驗
var passIsDiff = pass !== re_pass;
if (passIsDiff) {
ep.emit('info_error', '密碼與確認密碼不相等!'); // emit錯誤事件
return;
};
// 保存到數據庫
// 根據註冊信息去數據庫進行查詢驗證
UserModel.getUserBySignupInfo(username, email, function(err, users){
if (err) {
ep.emit('info_error', '獲取用戶信息失敗!');
return;
};
if (users.length > 0) {
ep.emit('info_error', '用戶名或者郵箱已存在!');
return;
};
// 保存用戶信息
UserModel.addUser({ username: username, pass: pass, email: email}, function(err, result){
if (result) {
res.render('sign/signup', {
success: '恭喜,註冊成功!'
});
} else {
ep.emit('info_error', '註冊失敗!');
};
});
});
};
// 渲染登錄頁面
exports.showSignin = function (req, res) {
res.render('sign/signin');
};
// 提交登錄信息
exports.signin = function (req, res) {
// 獲取表單數據
var username = req.body.name;
var pass = req.body.pass;
// 空校驗
if (!username || !pass) {
res.status(422);
return res.render('sign/signin', {error: '您填寫的表單信息不完整!'});
};
// 獲取用戶信息
UserModel.getUser(username, pass, function(err, user){
if (user) {
// 登錄成功, 保存用戶信息進入session
req.session.user = user;
res.render('sign/signin', {
success: '登錄成功!'
});
} else {
res.status(422);
res.render('sign/signin', {
success: '用戶名或者密碼有誤!'
});
};
});
};
// 處理登出
exports.signout = function (req, res) {
// 銷燬session
req.session.destroy();
// 重定向到首頁
res.redirect('/');
};複製代碼
原文地址: cnode系列之登錄註冊功能
倉庫代碼:cnoderedis