天天看點

node MongoDB做管理背景接口(注冊登入)

知識點

1、node

2、express

3、Mongoose

4、ES6

連接配接資料庫

mongodb的位址我們一般需要配置在config檔案中,做環境隔離,畢竟我們開發、測試、準生産、生産環境連接配接的資料庫位址是不一樣的,配置在config檔案中,我們直接通過啟動指令或者打包指令就可以切換到我們需要的mongodb位址,是開發必不可少的。

你可以使用

mongoose.connect()

方法連接配接 MongoDB 。

//資料庫位址
api:{
 db:mongodb://賬戶:密碼@位址:端口/資料庫名字
}
//封裝連接配接資料庫代碼
import mongoose from 'mongoose';
import errorEnum from './errorEnum';
const connect = () => {
    return new Promise((res, rej) => {
        try {
            mongoose.connect(__API__.db, (err) => {
              if (err) {
                rej(errorEnum.DB_CONNECT())
              } else {
                res();
              }
            })
        } catch (err) {
            rej(errorEnum.DB_CONNECT())
        }
    })
}
export {connect}
           

其中

errorEnum

是我們集中處理異常碼的檔案,看一下代碼,我們把所有需要抛給前端的錯誤碼在這處理,清晰便于維護。

import resh from '../helpers/responseHelper';
const DB_CONNECT = () => {
    return resh.failureResponse('連接配接資料庫失敗', '1001')
}
...
export default {DB_CONNECT}
           

responseHelper

中我們做的是把傳回給前端接口的

json

格式進行封裝,按照上文的異常情況傳回給前端的應該是

{desc:'連接配接資料庫失敗',code:'1001',body:{}}

,前端就可以根據錯誤碼做資料庫連接配接失敗的異常處理機制。

const failureResponse = (desc, code) => {
    return {
        desc: desc,
        code: code,
        body: {}
    }
}
...
export default {
    failureResponse,
    ...
}
           

使用者注冊

1、使用者輸入賬号(郵箱)密碼注冊賬戶

2、拿賬号在資料庫中查詢賬号是否已經存在,存在抛異常

3、賬号在資料庫中沒有存在,則把賬号資訊存入資料庫,存成功傳回注冊成功

定義一個Schema 、建立一個Model

Mongoose 的一切始于 Schema。每個 schema 都會映射到一個 MongoDB collection ,并定義這個collection裡的文檔的構成。

//我是 UserRegister.js
import mongoose from 'mongoose';
const registerSchema = new mongoose.Schema({
    id: String,
    mail: String,
    password: String,
    role:Array
}, {collection: 'user_register'});
module.exports = mongoose.model('user_register', registerSchema);
           

document 裡每個屬性的類型都會被轉換為 在

blogSchema

裡定義對應的

SchemaType

如上

mail

屬性會被轉化為SchemaType String,

role

屬性會被轉化為SchemaType Array,其實簡單的說就是存在資料庫中的類型,我們存的時候需要傳的類型。

我們要把 schema 轉換為一個 Model 使用

mongoose.model(modelName, schema)

函數,如上

module.exports = mongoose.model('user_register', registerSchema);

就是把

registerSchema

轉化為Model,以後的增删改查都要通過這個Model實作。

user_register

是在資料庫中的表名,如下圖,user_register表裡邊的資料結構跟schema中我們定義的對應一下,其中_id是mongodb自己生成的,是個對象,支援排序。

node MongoDB做管理背景接口(注冊登入)

圖1.資料庫顯示

資料庫 增、查、改、删

find

方法可按條件查詢資料庫

save

提供往資料庫新增一條資料的方法,繼續以使用者注冊為例

下邊接口的入參:

{mail:'[email protected]',password:'123456'}

增加完畢以後就如 圖1 中所示,在資料庫中插入一條資料,但是

role

[]

//定義Schema 建立Model的檔案
import Register from '../model/UserRegister';
const register = (req,res)=>{
  const _params = req.body.data;//取得接口傳過來的資料
  //此處省略對參數校驗的過程,假設傳過來的都是合法參數,但實際項目我們還是需要校驗的
  const _findParams = {mail:_params.mail};
  //用賬号去資料庫中查找賬号是否已經注冊
  Register.find(_findParams, (err, data) => {
    if ( err ) {
      //抛出異常
    } else {
      //data是我們查資料庫得到的資料,沒有查到為[]
      if(data == 0){
        const register = new Register({
          ..._params,
        });
        register.save((err)=>{
          if(err){
            //資料庫異常
          }else{
            //儲存成功
            mongoose.disconnect();
          }
        });
      }else{
        //提示使用者該賬戶已經注冊
      }
    }     
  });
}
export default {register}
           

update

提供了更新資料庫的方法,也就是我們說的 “改”

用法

Model.update(condition,doc,[options],[callback]);

condition

:更新的條件,要求是一個對象。

doc

:要更新的内容,要求是一個對象。

[options]

:可選參數,要求也是一個對象。

[callback]

:可選參數,要求是一個回調函數。

如下接口的入參:

{id:'10011',role:['user']}

接口提供的是給一個使用者配置設定權限的服務,初始注冊權限為

[]

//定義Schema 建立Model的檔案
import Register from '../model/UserRegister';
const setAuthority = (req, res) => {
    const _params = req.body.data;
    const _id = _params.id;
    //根據id查到對應的資料,将role參數更新
    Register.update({_id: _id}, {$set: {role: _params.role}}, (err) => {
        if (err) {
            //資料庫異常
        } else {
            //修改成功
        }
        mongoose.disconnect();
    })
}
export default {setAuthority}
           

$set

用來指定一個鍵并更新鍵值,若鍵不存在并建立

登入使用

update

登入的特殊性要求我們必須去更新資料庫,畢竟我們不希望同樣的賬戶可以到處登入,我們必須保證一個賬号在登入表裡隻有一條記錄,這樣後登入的就覆寫先登入的,先登入的再次請求接口就會報

token

異常了。

存登入資訊我們需要另一張表,就是說我們需要一個新的Schema,Model,上文已經介紹了怎麼建立,這裡就不重複說明了。

{mail:'[email protected]',password:'123456'}

//定義Schema 建立Model的檔案
import Login from '../model/UserLogin';
import Register from '../model/UserRegister';
const login=(req,res)=>{
  const _params = req.body.data;//取得接口傳過來的資料
  //此處省略參數校驗過程
  //先去系統資料庫查詢目前的登入的賬号是否注冊
  Register.find(_findParams, (err, data) => {
    if ( err ) {
      //抛出異常
    } else {
      //data是我們查資料庫得到的資料,沒有查到為[]
      if(data == 0){
        //提示使用者沒有注冊
      }else{
        const _user = data[0];//取到注冊資料
        //比較使用者輸入的密碼和系統資料庫裡的密碼是否相等
        if(_params['password']===_user['password']){
          //生成token
          const _token = uuid.v1();
          const _params = {
            ..._value,
            role: _user.role,//把注冊裡邊的角色也儲存到登入表裡邊
            token: _token
          };
          //賬号和密碼都比對,這個時候使用系統資料庫裡的id去登入表裡邊查詢資料,沒有查到就建立,查到就更新。
          Login.upadate((_id:_user['_id']),{$set:{..._params}},{usert:true},(err)=>{
            if(err){
              //資料庫錯誤
            }else{
              //儲存成功 把token和role傳回
            }
            mongoose.disconnect();//斷開資料庫連接配接
          }
        }else{
          //密碼錯誤
        }
      }
    }     
  });
}
           

upsert

boolean,如果不比對,是否建立文檔預設false,上邊代碼中用

upsert

是為了如果沒有在登入表中查到登入資訊就新增一條登入資料,如果查到了就更新資料。

擴充知識點

uuid

提供生成唯一辨別的兩個方法

npm install uuid --save

uuid.v1()

是基于時間戳生成的uid

uuid.v4()

是随機生成的uid

兩者相比較當然是

v1

更好用了,

v4

還是有重複的可能

remove

提供了删除資料的方法

以登入為例子,我們拿到token去登入表裡查使用者的登入資訊,查到了就删除。

{token:'123'}

//定義Schema 建立Model的檔案
import Login from '../model/UserLogin';
//登出
const logout = (req, res) => {
    const _params = req.body.data;//取得接口傳過來的資料
    //使用token去查找
    Login.remove({token: _params.token}, (err) => {
        if (err) {
            //資料庫異常
        } else {
            //删除成功
        }
    })
}
export default {
  logout
}
           

補充:前端在調用登出接口的時候一定要異步調用,前端自己要做清除緩存,跳轉登入頁面的操作,隻是通知背景我退出了,即使接口調用失敗前端也應該正常退出,下次登入的話就更新資料庫呗。

如果前端等到登出接口傳回成功再做操作,有幾率使用者一直退出不了。