二、node系列之數據接口註冊接口的實現(token驗證登陸)

1、使用express腳手架創建項目

// 安裝腳手架,只需安裝一次
npm i express-generator -g
// 創建express項目
express myapp --view=ejs
cd myapp
// 安裝依賴
npm i 
// 安裝需要使用的模塊
// 數據庫模塊 用戶唯一id模塊 密碼加密模塊 token模塊
npm i mongoose node-uuid bcryptjs jsonwebtoken -S

2、瞭解項目的目錄結構

  • bin
    www ------- 服務器啓動
  • node_modules ------- 項目的依賴文件
  • public ------- 靜態資源文件夾
    images ------- 靜態圖片
    javascripts ------- 靜態的js文件
    stylesheets ------- 靜態的樣式表文件
  • routes ------- 路由文件
    index.js ------- 默認的路由
    users.js ------- 用戶相關的路由
  • views ------- 路由對應的頁面
    index.ejs ------- 默認的首頁
    error.ejs ------- 錯誤頁面
    app.js ------- 使用中間件,註冊路由
    package.json ------- 描述文件

3、準備數據庫相關文件

大勳在node系列之數據庫mongoose的封裝中給大家介紹瞭如何封裝mongoose,可以先行查看如何封裝,封裝的文件夾爲sql,如果不想看的,可以直接通過網盤下載該文件夾

將該sql文件放置項目的跟目錄下

- myapp
	- sql
		- collection
			users.js
		db.js
		index.js

4、編寫註冊接口

  • 目標文件: myapp/routes/users.js

  • 實現思路:使用post提交數據的方式,先以手機號查詢有沒有該用戶,如果有該用戶,提示用戶該賬號已經註冊過了;如果沒有該用戶,則可以完成註冊,首先得將密碼加密,加密完成後插入數據庫

  • 代碼實現:

// 找到用戶集合
var User = require('./../sql/collection/users');
// 找到數據庫封裝文件
var sql = require('./../sql');
// 狀態碼的封裝
var utils = require('./../utils')
// 用戶唯一標識的id
var uuid = require('node-uuid');
// 密碼加密模塊
var bcrypt = require('bcryptjs');
var salt = bcrypt.genSaltSync(10); // 加密級別

// 實現註冊接口 -- post提交方式
router.post('/register', (req, res, next) => {
  // 1、先獲取表單信息
  let { username, password, tel } = req.body;
  // 2、根據手機號查詢 用戶集合中是否有該用戶,如果有,返回有該賬戶,如果沒有註冊繼續
  sql.find(User, { tel }, { _id: 0 }).then(data => {
    // 2.1 判斷有沒有該用戶
    if (data.length === 0) {
      // 2.2 沒有該用戶----繼續完成註冊操作
      // 2.2.1 生成用戶的id
      let userid = 'users_' + uuid.v1();
      // 2.2.2 對密碼加密
      password = bcrypt.hashSync(password, salt)
      // 2.2.3 插入數據庫
      sql.insert(User, { userid, username, password, tel}).then(() => {
        res.send(utils.registersuccess)
      })
    } else {
      // 2.3 已有該用戶
      res.send(utils.registered)
    }
  })
})
  • 附 狀態碼封裝模塊 myapp/utils/index.js
module.exports = {
  registered: {
    code: '10000',
    message: '該用戶已註冊,請直接登錄' 
  },
  registersuccess: {
    code: '10101',
    message: '註冊成功' 
  }
}

5、編寫登陸接口

  • 目標文件 myapp/routes/users.js
  • 實現思路:根據手機號查詢有沒有該用戶,如果沒有,提示用戶未註冊,如果有該用戶,使用bcryptjs模塊驗證密碼的有效性,如果有效,生成token,返回給前端相應的token值。
var jwt = require('jsonwebtoken');
// 實現登陸功能
router.post('/login', (req, res, next) => {
  // 1、獲取表單信息
  let { tel, password } = req.body;
  // 2、依據手機號查詢有沒有該用戶
  sql.find(User, { tel }, { _id: 0 }).then(data => {
    // 2.1 判斷有麼有該用戶
    if (data.length === 0) {
      // 2.2 沒有該用戶
      res.send(utils.unregister)
    } else {
      // 2.3 有該用戶,驗證密碼
      // 2.3.1 獲取數據庫中的密碼
      let pwd = data[0].password;
      // 2.3.2 比較 輸入的 密碼和數據庫中的密碼
      var flag = bcrypt.compareSync(password, pwd) // 前爲輸入,後爲數據庫
      if (flag) {
        // 2.3.3 密碼正確,生成token
        let userid = data[0].userid
        let username = data[0].username
        let token = jwt.sign({ userid, username }, 'daxunxun', {
          expiresIn: 60*60*24// 授權時效24小時
        })
        res.send({
          code: '10010',
          message: '登陸成功',
          token: token
        })
      } else {
        // 2.3.4 密碼錯誤
        res.send({
          code: '10100',
          message: '密碼錯誤'
        })
      }
    }
  })
})

6、驗證登陸實現

  • 目標文件: myapp/app.js
  • 實現思路:很多的數據請求都需要登陸之後才能獲取到,在此統一封裝驗證登陸
// 引入token模塊
var jwt = require('jsonwebtoken');
// 全局的路由匹配
app.use((req, res, next) => {
 // 排除登陸註冊頁面
  if (req.url !== '/users/login' && req.url !== '/users/register') {
  // 不同形式獲取token值
    let token = req.headers.token || req.query.token || req.body.token;
    // 如果存在token ---- 驗證
    if (token) {
      jwt.verify(token, 'daxunxun', function(err, decoded) {
        if (err) {
          res.send({ 
            code: '10119', 
            message: '沒有找到token.' 
          });
        } else {
          req.decoded = decoded;  
          console.log('驗證成功', decoded);
          next()
        }
      }) 
    } else { // 不存在 - 告訴用戶---意味着未登錄
      res.send({ 
        code: '10119', 
        message: '沒有找到token.' 
      });
    }
  } else {
    next()
  }
})

7、預告

下次分享node系列之產品數據的excel數據導入以及查詢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章