前篇
前言
首先要記錄的是登錄模塊
這里使用的是
mysql+JsonWebToken
koa2環(huán)境搭建
圖省事可以直接使用koa-generator直接生成koa腳手架
首先使用vue-cli
搭建vue腳手架
在cli
根目錄下新建server
目錄,用來放置服務(wù)端的代碼
并在cli
根目錄下新建app.js
文件,用來啟動(dòng)koa
在server
文件夾內(nèi)新建以下文件夾及文件
// 使用`tree /f`命令行生成文檔樹
// `tree /f > tree.txt`保存文檔樹
├─config // 各類配置的文件夾
│ db.js
│
├─controllers // 控制器
│ user.js
│
├─models // 模型
│ user.js
│
├─routes // 路由
│ user.js
│
├─schema // 數(shù)據(jù)庫表結(jié)構(gòu)
│ user.js
│
└─sql
user.sql
koa組件
"koa": "^2.3.0",
"koa-bodyparser": "^4.2.0", // 將post數(shù)據(jù)存入ctx.request.body
"koa-json": "^2.0.2", // 美觀的輸出JSON response
"koa-logger": "^3.0.1", // 打印http請(qǐng)求
"koa-router": "^7.2.1", // 路由
"koa-static": "^4.0.1", // 靜態(tài)文件服務(wù)
"koa2-history-api-fallback": "^0.0.5" // 解決vue前端路由與后端路由的沖突
mysql建表
(具體建庫建表代碼見)
先在自己的mysql
數(shù)據(jù)庫website
創(chuàng)建一個(gè)數(shù)據(jù)庫和表user
user
內(nèi)包含字段account
和passwd
并且insert
自己的賬戶密碼(mysql基礎(chǔ)不解釋)
Sequelize
后臺(tái)為了更方便得和數(shù)據(jù)庫進(jìn)行聯(lián)系述暂,這里使用Sequelize
模塊進(jìn)行增刪改查操作斥难,
sequelize
也支持promise
sequelize-auto
模塊可以將我們的數(shù)據(jù)庫的表結(jié)構(gòu)導(dǎo)出來
// 安裝模塊
npm i sequelize-auto && npm i sequelize mysql
進(jìn)入server的目錄,執(zhí)行如下語句sequelize-auto -o "./schema" -d website -h 127.0.0.1 -u root -p 3306 -x XXXXX -e mysql
,(其中 -o 參數(shù)后面的是輸出的文件夾目錄, -d 參數(shù)后面的是數(shù)據(jù)庫名, -h 參數(shù)后面是數(shù)據(jù)庫地址胁孙, -u 參數(shù)后面是數(shù)據(jù)庫用戶名唠倦, -p 參數(shù)后面是端口號(hào), -x 參數(shù)后面是數(shù)據(jù)庫密碼涮较,這個(gè)要根據(jù)自己的數(shù)據(jù)庫密碼來稠鼻! -e 參數(shù)后面指定數(shù)據(jù)庫為mysql)
執(zhí)行完就會(huì)在schema
文件夾中生成user.js
文件(user數(shù)據(jù)表結(jié)構(gòu))
sequelize-auto報(bào)錯(cuò)?
沒有報(bào)錯(cuò)者請(qǐng)無視這條
若在window環(huán)境下使用sequelize-auto
報(bào)錯(cuò)
就直接在sequelize-auto
模塊的\bin
目錄下執(zhí)行
node sequelize-auto -o "./schema" -d website -h 127.0.0.1 -u root -p 3306 -x XXXXX -e mysql
再將生成的user.js
復(fù)制到schema
文件夾內(nèi)
初始化數(shù)據(jù)庫配置
在server
目錄下的config
目錄下我們新建一個(gè)db.js
狂票,用于初始化Sequelize
和數(shù)據(jù)庫的連接候齿。
// db.js
const Sequelize = require('sequelize'); // 引入sequelize
// 使用url連接的形式進(jìn)行連接,注意將root: 后面的XXXX改成自己數(shù)據(jù)庫的密碼
const Website = new Sequelize('mysql://root:XXXX@localhost/website',{
define: {
timestamps: false // 取消Sequelzie自動(dòng)給數(shù)據(jù)表加入時(shí)間戳(createdAt以及updatedAt)
}
})
module.exports = {
Website // 將Todolist暴露出接口方便Model調(diào)用
}
建立model模型
// models/user.js
const db = require('../config/db.js')
const userModel = '../schema/user.js'
const WebsiteDb = db.Website // 引入數(shù)據(jù)庫
const User = WebsiteDb.import(userModel) // 導(dǎo)入數(shù)據(jù)模型
// 返回匹配到的user信息
const getUserByAccount = async (account) => {
const userInfo = await User.findOne({
where: {
account: account
}
})
return userInfo
}
module.exports = {
getUserByAccount
}
controller控制器
// controllers/user.js
const jwt = require('jsonwebtoken')
const user = require ('../models/user.js')
// 執(zhí)行model方法返回user表匹配信息闺属,并對(duì)信息進(jìn)行jwt操作并返回
const postSingin = async (ctx) => {
const data = ctx.request.body
const userInfo = await user.getUserByAccount(data.account)
if(userInfo !== null) {
if(data.passwd !== userInfo.passwd) {
ctx.body = {
success: false,
info: '密碼錯(cuò)誤'
}
} else {
const userToken = {
name: userInfo.account,
id: userInfo.id
}
const secret = 'cheesekun-website'
const token = jwt.sign(userToken, secret)
ctx.body = {
success: true,
token: token
}
}
}else {
ctx.body = {
success: false,
info: '用戶不存在'
}
}
}
module.exports = {
postSingin
}
定義路由
// routes/user.js
const user = require('../controllers/user.js')
const router = require('koa-router')()
router.post('/user', user.postSingin)
module.exports = router
app.js入口配置
const Koa = require('koa')
const Router = require('koa-router')()
const json = require('koa-json')
const logger = require('koa-logger')
const bodyParser = require('koa-bodyparser')
const static = require('koa-static')
const historyApiFallback = require('koa2-history-api-fallback')
const path = require('path')
const app = new Koa()
const user = require('./server/routes/user.js')
app.use(bodyParser())
app.use(json()) // 美化返回的 json
app.use(logger())
app.on('error', async(err, ctx) => {
console.log('server error', err)
})
Router.use('/api', user.routes())
app.use(Router.routes())
app.listen(8889, () => {
console.log('koa2 server in 8889')
})
vue登陸模塊
樣式?jīng)]什么好說的慌盯,使用了ElementUI
請(qǐng)求方面使用了axios
// src/main.js
import axios from 'axios'
// ... 省略
Vue.config.productionTip = false
// 將axios給vue實(shí)例
// 之后在vue中就可以直接使用`this.$http`來代替引入axios
Vue.prototype.$http = axios
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
this.$message
是ElementUI
的一個(gè)組件用法,具體可看ElementUI
// src/components/signin/signin.vue
signin() {
const signinObj = {
account: this.account,
passwd: this.passwd
}
this.$http.post('/api/user', signinObj)
.then((res) => {
if(res.data.success) {
sessionStorage.setItem('token', res.data.token) // 將jwt存入sessionStorage
this.$message({
type: 'success',
message: '登錄成功'
})
this.$router.push({path: '/music'})
}else {
this.$message.error(res.data.info)
sessionStorage.setItem('token', null)
}
})
.catch((err) => {
this.$message.error('請(qǐng)求錯(cuò)誤掂器!')
sessionStorage.setItem('token', null)
})
}
結(jié)語
登陸模塊僅僅將jwt存儲(chǔ)在sessionStorage
以此來判斷該用戶有無登陸過該網(wǎng)站
并沒有密碼加密和使用其他類似于會(huì)話之類
這個(gè)只能之后了解到相關(guān)的用法再進(jìn)行升級(jí)了
結(jié)語2
這是一篇要配合github代碼才能看得明白的文章
有種像是寫個(gè)自己看的感覺orz