問卷系統

問卷系統開發 ---服務端

github:https://github.com/Snail017/testsystem-mysql-express.git

1. 數據庫建表

  • redis 數據庫 (存放token,做爲輔助數據庫)css

    redis 查詢速度快,可是做爲內存數據庫,沒法存儲過大數據。存放緩存有助於提升性能
  • mysql 數據庫 (存放大規模數據,做爲主數據庫)html

    存儲在硬盤中。能夠支持更大規模的數據,成本更低。

使用sequelize 操做mysql數據庫。

5d36c713ab64414b8a00267c.png

出卷人要指定答卷人,

建了一個 關聯指定答卷人和試卷table,

產品需求須要一個答卷人列表,須要根據答卷的狀態,關鍵字進行搜索,

建表 就須要先在 指定答卷人和試卷table 里根據user_id獲得他所須要考試的全部試卷,而後逐個篩選狀態和關鍵字

實戰:ORM數據模型(Object/Relational Mapping)

將數據庫操做經過實例對象的語法完成。使用框架sequlize
  • 數據庫table  --->  類(class)
  • 記錄(record,行數據)---> 對象(object)
  • 字段(filed)-->對象屬性(attribute)

命名規範:前端

  1. 一個類對應一張表。類名是單數,且首字母大寫;表名是複數,且所有是小寫。好比,表books對應類Book
  2. 若是名字是不規則複數,則類名依照英語習慣命名,好比,表mice對應類Mouse,表people對應類Person
  3. 若是名字包含多個單詞,那麼類名使用首字母所有大寫的駱駝拼寫法,而表名使用下劃線分隔的小寫單詞。好比,表book_clubs對應類BookClub,表line_items對應類LineItem
  4. 每一個表都必須有一個主鍵字段,一般是叫作id的整數字段。外鍵字段名約定爲單數的表名 + 下劃線 + id,好比item_id表示該字段對應items表的id字段。

感受這樣好複雜,有沒有更好的建表方式,或者處理方式?vue

2.數據加密

加密的兩種方式

1.RES非對稱加密:加密解密的祕鑰不一樣,私鑰加密,公鑰解密。
5ceb4754ab64413019001458.pngmysql

  1. AES對稱加密
實戰:使用RES 加密用戶信息

使用加密插件crypto,進行RES非對稱加密+md5不可逆加密
5ceb5273ab6441301900167c.pngjquery

關於加密解密引用一則動漫解讀:https://mp.weixin.qq.com/s/1ojSrhc9LZV8zlX6YblMtAwebpack

3.用戶認證

用戶認證方法   token方法和session認證
  • 目的:防止CSRF(cross-site request forgery)網站攻擊。
  • 網站攻擊經常使用的兩種方式:XSS,CSRF;ios

    CSRF:查看wiki解釋。
    防護方式:1.檢查refrence 字段  2.添加token
  • CSS:代碼注入git

    防護措施:htmlentites  過濾輸出。
1.token認證:JWT實現

5ceb81f5ab64412e23001f04.png

  • JWT的組成:Header + Payload + Signature
  • JWT 優勢:github

    1. 可拓展性好。(session須要放在數據庫中,可是jwt只須要放在客戶端中)
    2. 無狀態(JWT 不在服務端存儲任何狀態)
  • JWT缺點:

    1. 安全性(bse64編碼,沒有加密)
    2. 性能(JWT數據比較長 ,通常存儲在localstorage中)
    3. 一次性
2.傳統session認證

5ceb81ecab64413019001fc9.png

實戰:用戶自動登陸(JWT實現)

設置token自動刷新時間

  • 用戶登陸時設置access_token 和refresh_token,access-token爲key,fresh_token爲value存入redis數據庫。並將access_token返回給客戶端。access_token時間能夠設置爲1個小時,refresh_token時間設置爲一週(refresh_token有效時間越長,token有效期越長)。

    > 1. 當時access_token 失效時,根據access_toke獲得refresh_token判斷是否有效。
    > 2. 有效返回新的access_token給客戶端,設置Authorization。將新的access_token 和refresh_token存入redis數據庫。
    > 3. 無效從新登陸。
    >


問卷系統開發 --- 前端

1. vue.config.js 配置

使用 dev-server 代理請求

具體使用能夠參考文檔webpack中文網

const path = require('path');

function resolve(_dir) {
    return path.join(__dirname, _dir)
}
const webpack = require("webpack")
let webpackConfig = {
    configureWebpack: {
        plugins: [
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                "windows.jQuery": "jquery"
            }),
        ]
    },

    chainWebpack: config => {
        config.resolve.alias.set('@', resolve('/src'));
        config.resolve.symlinks(true);
    },

    devServer: {
        hot: true,
        disableHostCheck: true,
        // 設置代理
        proxy: {
            '/': {
                ws: false,
                target: 'http://localhost:3000',
                changeOrigin: true,     //爲true,本地能夠虛擬一個服務器接受請求並代理髮送該請求
                pathRewrite: {
                    '^/': '/'
                }
            },
        }
    },

    css: {
      extract: false
    }
}
module.exports = webpackConfig;

2. main.js 獲取公鑰

路徑 :/src/main.js
項目執行獲取公鑰存儲在瀏覽器localStorage

//獲取公鑰
Vue.prototype.$http({
    method: 'get',
    url: "/publicKey",
}).then((res) => {
    res = res.data;
    if (res.code == 200) {
        window.localStorage.setItem("public_key", res.msg);
    }
})

3. http.js 設置路由防備

驗證token 每次路由跳轉作權限校驗
import axios from 'axios';
import router from './router';

//定義一個路由防衛,每次路由跳轉,咱們都來作一下權限校驗
router.beforeEach((to, from, next) => {
    if (to.meta.requireAuth) {  // 判斷該路由是否須要登陸權限
      if (localStorage.token&&localStorage.token!='') { //判斷token是否存在
        console.log("token存在");
        next();
      } else {
        console.log("token不存在");
        next({
          path: '/login', // 將跳轉的路由path做爲參數,登陸成功後跳轉到該路由
          query: {redirect: to.fullPath}
        })
      }
    }
    else { // 若是不須要權限校驗,直接進入路由界面
      next();
    }
  });
  
// http request 攔截器
axios.interceptors.request.use(
  config => {
    if (localStorage.token) { //判斷token是否存在
      config.headers.Authorization = localStorage.token;  //將token設置成請求頭
    }
    return config;
  },
  err => {
    return Promise.reject(err);
  }
);

// http response 攔截器
axios.interceptors.response.use(
  response => {
    if (response.data.code === 401) {
      router.replace('/login');
      console.log("token過時");
    }else if(response.headers.authorization){
      localStorage.token=response.headers.authorization;
    }
    return response;
  },
  error => {
    return Promise.reject(error);
  }
);
export default axios;

摸索學習,有什麼不對的歡迎指教。

相關文章
相關標籤/搜索