导语:
暑假在家闲着无事,就琢磨着做一个web博客练练手,现在已经做完了,把过程分享出来给大家看看,分享一下学习经验。这是第六篇,开始编写后台接口,为前端接口提供提供基础,主要讲node,koa2,redis,mysql的连接和接口的编写。
我们先创建一个conf目录,下面再创建一个db.js用来存放msyql和reids的配置,创建一个controller用来编写各个部分的路由接口,创建一个db下面mysql.js用来统一执行sql语句。
const env = process.env.NODE_ENV
let MYSQL_CONF
let REDIS_CONF
if (env === 'dev') {
MYSQL_CONF = {
host: 'localhost',
user: 'root',
password: '********',
port: '3306',
database: 'myarticle'
}
//redis_conf
REDIS_CONF = {
port: 6379,
host: '127.0.0.1'
}
}
if (env === 'production') {
//mysql
MYSQL_CONF = {
host: '172.29.75.29',
user: 'root',
password: '*********',
port: '3306',
database: 'myarticle'
}
//redis_conf
REDIS_CONF = {
port: 6379,
host: '172.29.75.29'
}
}
module.exports = {
MYSQL_CONF,
REDIS_CONF
}
db文件夹下面的mysql.js,用来统一执行sql语句
const mysql = require('mysql')
const { MYSQL_CONF } = require('../conf/db')
// 创建链接对象
const con = mysql.createConnection(MYSQL_CONF)
// 开始链接
con.connect()
// 统一执行 sql 的函数
function exec(sql) {
const promise = new Promise((resolve, reject) => {
con.query(sql, (err, result) => {
if (err) {
reject(err)
return
}
resolve(result)
})
})
return promise
}
module.exports = {
exec,
escape: mysql.escape
}
到这里我们就已经用代码把mysql和我们的node后台连接在一起了,可以直接在代码中使用sql语句操作数据库。
这里我们的登陆要做成session,所以我们要在app.js里面做一些操作。补充一部分代码。
const session = require('koa-generic-session')
const redisStore = require('koa-redis')
//session配置
app.keys = ['xiaomizhou12345']
app.use(session({
//配饰cookie
cookie: {
path: '/',
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000
},
//配置redis
store: redisStore({
all: '127.0.0.1:6379' //写死本地redis
})
}))
const router = require('koa-router')()
const path = require('path')
const fs = require('fs')
const { login, signup, updataavatar, updataname } = require('../controller/user')
const { SuccessModel, ErrorModel } = require('../model/resModel')
router.prefix('/api/user')
const env = process.env.NODE_ENV
//登陆
router.post('/login', async function (ctx, next) {
const { username, password } = ctx.request.body
const data = await login(username, password)
//console.log(data.username)
if (data.username) {
ctx.session.username = data.username
ctx.session.realname = data.realname
ctx.body = new SuccessModel(data)
return
}
ctx.body = new ErrorModel('登陆失败')
})
//注册
router.post('/signup', async function (ctx, next) {
const { username, password, realname, email } = ctx.request.body
const data = await signup(username, password, realname, email)
// console.log(data)
// console.log(data.num)
if (data.num == 0) {
ctx.body = new SuccessModel("注册成功",data.id)
return
}
ctx.body = new ErrorModel('注册失败')
})
module.exports = router
接口调用后使用await函数,让sql语句去执行,最后把执行的结果回传回来。我们先来看一下controller文件夹里面关于signup和login的函数是怎么写的。
const { exec, escape } = require('../db/mysql')
const { genPassword } = require('../utils/cryp')
//登陆
const login = async (username, password) => {
username = escape(username)
// 生成加密密码
password = genPassword(password)
password = escape(password)
console.log(password)
const sql = `
select username, realname, avatar, likes, goods from users where username=${username} and passworded=${password}
`
const rows = await exec(sql)
return rows[0] || {}
}
// 注册
const signup = async (username, password, realname, email) => {
username = escape(username)
// 生成加密密码
password = genPassword(password)
password = escape(password)
let test = `select username from users where username=${username}` //注册时检验有无相同账号
const testData = await exec(test)
console.log(testData,testData.length)
if (testData.length > 0) {
return {
num: testData.length,
id: 0
}
}
const sql = `
insert into users (username, realname, passworded, email, likes, goods) values (${username}, '${realname}', ${password}, '${email}', '', '');
` //注册
const insertData = await exec(sql)
return {
num: 0,
id: insertData.insertId
}
}
我们可以看到注册执行函数在注册钱先去执行了这个账户有没有被注册,如果被注册了的话就会返回已经被注册的信息出来,如果没有注册将继续执行下面的操作。
我们对于账户的信息肯定是要注重安全的,所以我们要给账户的密码加密,让用户在注册的时候,如果密码是123,经过加密后会生成一串加密码。现在我们来看一下加密函数。
const crypto = require('crypto')
//密匙
const SECRET_KEY = 'xiaomizhou12345#'
//加密
function md5(content) {
let md5 = crypto.createHash('md5')
return md5.update(content).digest('hex')
}
function genPassword(password) {
const str = `password=${password}&key=${SECRET_KEY}`
return md5(str)
}
module.exports = {
genPassword
}
这样加密后的密码,只有用户输入跟注册时候的123,转变成一串加密码,跟数据库的加密码一样才能登陆成功。这样就算数据库被泄露了,黑客也很难登陆我们的账号,同时账号输入这里也做了一层防御sql注入的手段,即
username = escape(username)
password = escape(password)
全面保护数据的安全,这样才是一个合格的后台程序和数据库。
补充:
微信搜索【web小馆】,回复全栈博客项目,即可获取项目源码和后续的实战文章教程。每天用最简单朴实的语言,潜移默化的提升你的计算机基础知识和前端技术。小米粥,一个专注的web全栈工程师,我们下期再见!