⋅⋅⋅書接上回,咱們搭建了WEB服務端路由、模板等功能,完成了register 經過ajax與後端的通訊,今天主要完成數據與mongodb的存取,實現註冊 / 登陸 / 退出功能javascript
⋅⋅⋅DEMO GIT https://github.com/xiaolulu/mynodejs.gitcss
⋅⋅⋅上一節咱們已經安裝過了mongo,本節主要是對其操做前端
⋅⋅⋅nodejs對 mongo的操做,咱們使用 mongoose庫java
⋅⋅⋅在package.json添加mongoose,並npm installnode
⋅⋅⋅使用參考http://www.upopen.cn/article/info?id=559688a7f0e6e0665b000004git
javascriptvar mongoose = require( 'mongoose' ); //引用模塊 mongoose.connect( 'mongodb://127.0.0.1/myDB', function( err ){ //鏈接mongoose,鏈接本地127.0.0.1,mongo的默認端口是 27017 if( !err ){ console.log( 'DB == connect to mongodb' ); } else { throw err; } } ); var Schema = mongoose.Schema; var UserSchema = new Schema({ //建立User表模型,數據可據需求增減 username: String, password: String, email: String, disabled: Boolean, //後面加註冊後的郵件驗證功能 date: Date, power: Number //後面會用到權限功能 }); var UserModel = mongoose.model( 'User', UserSchema, 'User' ); function initData( data, db ){ //對參數作預處理,以防出現不合要求的參數,後面這塊會作擴展 var query = {}; for( var key in data ){ if( db.tree[ key ] ){ query[ key ] = data[ key ]; } } return query; } function addUser( data, cb ){ //增長用戶 data = initData( data, UserSchema ); ( new UserModel( data )).save( function( err, doc ){ cb( err, doc ); }) } function findUser( data, cb ){ //查找用戶 data = initData( data, UserSchema ); UserModel.findOne( data ).exec( function( err, doc ){ cb( err, doc ); }) } module.exports = { addUser: addUser, findUser: findUser }
javascriptvar db = require( '../db/sql' ); //添加前面定義的db操做模塊 function addUser( req, res ){ //增長用戶 var data = req.body; //post過來的數據在req.body裏,get過來的數據在req.query裏 data.date = new Date(); //數據裏增長時間 db.addUser( data, function( err, doc ){ if( !err ){ res.send( { code: 0, msg: 'add User Success', data: doc } ); //對查詢結果返回,返回格式統一爲 {code: 返回碼, msg: 返回描述, data: 返回值} } }) } function findUser( req, res ){ //查找用戶 var data = req.body; db.addUser( data, function( err, doc ){ if( !err ){ res.send( { code: 0, msg: 'find User Success', data: doc } ); } }) } module.exports = { addUser: addUser, findUser: findUser }
四、修改上節在/root/web/routes/issue.js定義的register函數改成
javascript
function registerUser( req, res ){ user.addUser( req, res ); }
⋅⋅⋅並增長 /web/controls/user.js的引用github
⋅⋅⋅再用node-dev啓動項目,訪問register,提交表單,能夠看到返回成功,至此咱們註冊用戶成功web
⋅⋅⋅打開shell,執行mongo,打開mongo終端ajax
⋅⋅⋅執行use myDB //切換到myDB數據庫redis
⋅⋅⋅執行db.User.find().pretty() //能夠看到剛纔咱們新增的數據
⋅⋅⋅在/root/web/views/issue下新建login.ejs,添加登陸form。
⋅⋅⋅在/root/static/module/issue 下新建 login的 js/css/img 靜態文件,添加登陸請求,如註冊。
⋅⋅⋅咱們在db操做/db.sql.js裏及業務處理/controls/user.js已經增長查詢方法,只需在/routes/index.js 及 issue裏增長 登陸查詢便可,這裏不在列出,參考 register 流程便可。
⋅⋅⋅上一步,咱們走通了註冊和登陸查詢功能,而後登陸的目的是爲了根據用戶登陸與否判斷是否具有訪問某些頁面的權限。
⋅⋅⋅這裏簡單說下session(後面再單獨詳解):網站保存信息或狀態,頁面端經常使用的是cookie,而對應服務端是session,登陸狀態須要保存服務端以防僞造頁面端。而http(後面再單獨詳解)是無狀態的,爲使頁面端與服務端關聯,生成session時,同時會在cookie裏寫入一個對應的id值,如 session_sid,每次頁面與服務器的交互都會自動帶上cookie,服務器端會據這個id查找是否有對應的session保存,從而造成狀態保存。
⋅⋅⋅這裏咱們也使用第三方庫 express-session,安裝同 mongoose
⋅⋅⋅在 /root/web/routes/index.js裏引入 express-session,並新增app.use以下
javascriptvar issue = require( './issue' ), session = require( 'express-session' ); //添加 express-session引用 exports.all = function( app ){ app.use( session({ //配置session resave: false, saveUninitialized: false, secret: 'upopen' })) app.use( function( req, res, next){ if( req.path != '/login' && !req.session.status ){ //判斷session狀態是不是true res.redirect('/login'); //不是則跳轉到登陸頁 } else { next(); //爲true,則繼續執行其請求 } }) app.get( '/', function( req, res ){ issue.index( req, res ); }); …
⋅⋅⋅上面的代碼是對全部的頁面作了限制,都必須是登陸的狀態才能訪問,因此前端要先有註冊成功的帳號,這樣的權限設置固然是不對的,咱們只是作下測試。
⋅⋅⋅打開/root/web/controls/user.js,在findUser函數下新增以下代碼
javascript… function findUser( req, res ){ var data = req.body; db.findUser( data, function( err, doc ){ if( !err ){ if( doc ){ //若是登陸有查找結果 req.session.status = true; //則session裏記錄狀態爲true } res.send( { code: 0, msg: 'find User Success', data: doc } ); } }) } …
⋅⋅⋅再打開站點測試,發現,不管是訪問index 仍是 register都是自動跳轉login,登陸信息成功後,index和register均可以訪問了,查看cookies裏的信息,會看到 自動生成的connect.sid(名稱可能不一樣),就是保存關聯session的。手動刪除connect.sid,全部頁面又會都跳轉到 login。
⋅⋅⋅cookie使用,可參考 http://www.upopen.cn/article/info?id=559e2cbda46ee1885f000002
⋅⋅⋅執行退出命令,只要設置req.session.status = false,便可。
⋅⋅⋅上一步,增長了頁面請求對權限登陸的驗證,可是驗證只是針對某些頁面的,咱們把須要驗證的路徑羅列下來。
⋅⋅⋅在/web/config下新增 privilege.js,用來羅列權限表,咱們新增幾個用戶管理頁面,用來表示權限須要
javascript
module.exports = { '/user/center' : 1, '/user/info': 1, '/user/blog': 1 }
⋅⋅⋅修改 /root/web/routes/index.js,引入/web/config/privilege.js,修改驗證是否登陸的app.use
javascript… var privilege = require( '../config/privilege' ); … app.use( function( req, res, next){ if( privilege[ req.path ] && req.path != '/login' && !req.session.status ){ //privilege[ req.path ] 判斷該路徑是否須要登陸權限 if( req.method == 'GET' ){ //若是是get請求 res.redirect('/login'); 則執行跳轉 } else { //其它請求,基本都是POST,是不能直接redirect res.send( { code: 1001, msg: 'need you to log in'}); //則返回錯誤碼,提示須要登陸 } } else { next(); } }) …
⋅⋅⋅在web/routes 、web/views、status/module,新增對應的用戶頁面,user/blog,user/info,user/center,添加時注意文件夾的命名及細分。
⋅⋅⋅清除cookie,再訪問 index 、register都是能夠的,而user下的三個頁面都須要登陸。
⋅⋅⋅在/root/static/public/js 下新建 all.js,用於全部頁面都要執行js
⋅⋅⋅將頁面據cookies判斷登陸狀態的js寫入,以便頁面導航上 顯示 登陸 或 退出,經過requirejs,在每一個頁面引入。
⋅⋅⋅退出,即給退出連接加一個get請求,/logout,在/routes/index.js裏,添加logout
javascript... app.get('/logout', function( req, res ){ req.session.status = false; //設置session狀態爲未登陸 res.setHeader("Set-Cookie","username=null;" ); //清除cookie res.redirect( '/' ); //跳轉到首頁 }) ...
⋅⋅⋅本節咱們主要完成:
⋅⋅⋅一、經過mongoose來操做mongo,完成數據增長和查詢
⋅⋅⋅二、經過session保存登陸狀態
⋅⋅⋅三、完成註冊 / 登陸 / 退出
⋅⋅⋅四、增長權限判斷
⋅⋅⋅本節咱們雖然使用了session來記錄登陸狀態,但實際使用時仍是會有些問題,session是保存在本項目裏的,若是上線後web服務端須要用多臺計算機來負載,則狀態不能共享。能夠採用搭建驗證服務器,即單獨配置一個服務器來執行驗證功能,也可使用redis來保存登陸狀態。下節咱們將使用redis來保存登陸狀態。
⋅⋅⋅下節主要實現:
⋅⋅⋅一、註冊時的郵件驗證
⋅⋅⋅二、redis保存登陸狀態
⋅⋅⋅三、nodejs異常處理,同步 and 異步
⋅⋅⋅四、git操做