一個關於vue+mysql+express的全棧項目(三)------ 登錄注冊功能的實現(已經密碼安全的設計)


本系列文章,主要是一個前端的視角來實現一些后端的功能,所以不會講太多的前端東西,主要是分享做這個項目學到的一些東西,,,,,

好了閑話不多說,我們開始搭建后端服務,這里我們采用node的express框架來做我們的后端服務

這里是官網地址:express

一、安裝express框架

npm install express --save

二、先寫一個測試的接口

在根目錄下新建一個server的文件夾,並新建一個server.js

 1 const express = require('express')
 2 
 3 const app = express()
 4 
 5 const Router = express.Router()
 6 
 7 Router.get('/test', function(req, res) {
 8   return res.json({
 9     code: 0,
10     data: 'hello world!'
11   })
12 })
13 
14 app.use('/testRouter', Router)
15 
16 app.listen(3001, function() {
17   console.log('express server is success')
18 });

接下來我們在node環境中運行server.js

打開瀏覽器,輸入localhost://3001/testRouter/test;可以看到以下結果

接下來就是安裝mysql,具體安裝參照百度

三,使用node做為服務端,來操作數據庫的話,我們最好選用一個orm,這樣可以方便我們更好的操作數據庫,想基於MongoDB有mongoose;mysql有sequelize

  這里因為我們的數據庫選用的是mysql,那么我們就選擇sequelize,首先安裝sequelize

npm install sequelize --save
npm install mysql2 --save

然后打開我們的數據庫命令窗口mysql,輸入密碼,默認密碼為root

創建一個數據庫

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [DEFAULT] CHARACTER SET [=] charset_name
{}表示參數必選 | 表示選擇一個
[]表示參數可選
{DATABASE | SCHEMA}任選其一
[IF NOT EXISTS] 可以忽略創建重復數據庫是,系統的報錯信息(從而產生一個警告)
CHARACTER SET [=] charset_name 指定數據庫編碼方式(DEFAULT可寫可不寫)

這里我們簡單創建一個數據庫vue_chat

CREATE DATABASE  vue_chat;

查看數據庫,使用:

SHOW DATABASES;

 

 
        

 四,使用sequelize鏈接數據庫

 在server目錄下新建db.js

const Sequelize = require('sequelize');
const sequelize = new Sequelize(
  'vue_chat', // 數據庫名
  'root',   // 用戶名
  'root',   // 用戶密碼
  {
      'dialect': 'mysql',  // 數據庫使用mysql
      'host': 'localhost', // 數據庫服務器ip
      'port': 3306,        // 數據庫服務器端口
      'define': {
          // 字段以下划線(_)來分割(默認是駝峰命名風格)
          'underscored': true
      }
  }
);

新建一個模型(這里模型對應的就是mysql中的表的概念,這里直接使用我之前定義好的模型,不過多解釋模型里面的字段(每個人設計模型或者表的思考方式都會有差異,這個東西根據項目來設計))const account = sequelize.define(

// tablename
  'account',
  {
    'user_name': {
      'type': Sequelize.STRING,
      'allowNull': false
    },
    'pwd': {
      'type': Sequelize.STRING,
      'allowNull': false
    },
    'email': {
      'type': Sequelize.STRING,
      'allowNull': true
    },
    'avatar': {
      'type': Sequelize.STRING,
      'allowNull': true
    },
    'user_info': {
      'type': Sequelize.STRING,
      'allowNull': true
    },
    'user_id': {
      'type': Sequelize.CHAR(64),
      'allowNull': false,
      'unique': true
    },
    'create_temp': {
      'type': Sequelize.DATE,
      'defaultValue': Sequelize.NOW,
    },
    'user_fans': {
      'type': Sequelize.INTEGER,
      'allowNull': false,
      'defaultValue': 0
    },
    'attention': {
      'type': Sequelize.BIGINT,
      'allowNull': false,
      'defaultValue': 0
    },
    'poetry_num': {
      'type': Sequelize.BIGINT,
      'allowNull': false,
      'defaultValue': 0
    }
  }
)
account.sync();
sequelize.authenticate().then(() => {
  console.log('Connection has been established successfully.');
}).catch(err => {
  console.error('Unable to connect to the database:', err);
});
module.exports
= sequelize

新建user.js

const express = require('express')

const Router = express.Router()

const sequelize = require('./db')
const account = sequelize.model('account')

const utility  = require('utility')


Router.post('/register', function(req, res) {
  // 用戶注冊
  const body = req.body.userinfo
  const {user_name, pwd} = req.body.userinfo
  const data = {
    user_name: user_name,
    pwd: pwdMd5(pwd),
    create_temp: new Date().getTime(),
    user_id: pwdMd5(Date.now())
  }
  account.create(data).then(doc => {
    const {user_name, user_id, user_info, avatar} = doc
    res.cookie('user_id', user_id)
    return res.json({
      code: 0,
      data: {
        user_name: user_name,
        user_id: user_id,
        user_info: user_info,
        avatar: avatar
      }
    })
  })
})

module.exports = Router

此時我們第一個接口也就是注冊接口已經寫完,接下來就是前后端聯調了

首先先去我們的前端設置請求代理,因為前端服務端口和我們后端服務接口不是同一個,所以存在跨域的問題

在根目錄下找到config文件夾,打開index.js文件進行修改

proxyTable: {
      '/api': {
        target: 'http://localhost:9094/',
        changeOrigin: true,
        pathRewrite: {
          '^/api': '/'
        }
      }
    },

緊接着,在我們之前新建好的api文件夾下,新建一個account.js

 

import * as axios from '../common/js/axios'

// 用戶注冊
const register = params => axios.post('/user/register', params)

export {
  register
}

五.對接接口

打開store中的action.js

import * as types from './mutation-types'
import { Loading } from '../Plugins/index'
import { register} from 'api/account'

const registerAccount = function ({commit, state}, {userinfo}) {
  // 用戶注冊
  // 這里返回一個Promise函數,方便在組件中知道當前接口是否請求完成
  return new Promise((resolve, reject) => {
    register({userinfo}).then(res => {
      if (res.status === 200 && res.data.code === 0) {
        resolve(res.data.data)
      } else {
        reject(new Error())
      }
    })
  })
}
export {
  registerAccount,
}

這里假設你已經寫好了注冊的前端的界面,下面是一個簡單的注冊界面

 

js交互假設你已經寫好了

import { mapActions } from 'vuex'
export default {
  data () {
    return {
      blurstate: false,
      user_name: '',
      pwd: ''
    }
  },
  methods: {
    handlerLogin () {
      if (!this.user_name) {
        this.$toast({
          state: true,
          desc: '請輸入用戶名'
        })
        return
      }
      if (!this.pwd) {
        this.$toast({
          state: true,
          desc: '請輸入密碼'
        })
        return
      }
      let userinfo = {
        user_name: this.user_name,
        pwd: this.pwd
      }
      this.userLogin({userinfo}).then(res => {
        if (res.status === 200 && res.data.code === 0) {
          this.$router.push({path: '/'})
        }
      })
    },
    toRgister () {
      this.$router.push({path: '/register'})
    },
    ...mapActions([
      'userLogin'
    ])
  }
}

點擊注冊,這個時候查看我們的數據庫是否已經正確寫入數據

切換到我們新建的數據庫
use vue_chat;
查看數據表
show tables;
查看數據表結構; desc accounts;
查看數據表中的數據 select * from accounts;

六、登錄注冊的模型的安全設計

上面的登錄注冊只是一個簡單的數據增刪改查,對於用戶的數據沒有絲毫安全性可言,只要攔截我們的登錄注冊接口即可拿到我們的用戶密碼,那么下圖就是我們改造后的登錄注冊模型

如上圖這個模型,即使我們的登錄接口被攔截了,那么也只能拿到一段MD5的加密字符串,根本無法獲取我們真實的密碼,而且這個加密串根本也和我們的數據庫存的加密串是不一致的,所以根本無法破解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM