# 四、Koa 与登录鉴权
# 1、cookie 与 session
① cookie 使用
const Router = require('koa-router')
const router = new Router()
router.get('/', async (ctx, next) => {
//获取cookie
console.log(ctx.cookies)
console.log(ctx.cookies.get('password'))
// 设置cookie
console.log(ctx.cookies.set('username', 'lencamo'))
})
module.exports = router
② session 使用
安装:
npm i koa-session-minimal
使用:
- index.js
const Koa = require('koa')
const views = require('koa-session-minimal')
const app = new Koa()
// session配置
app.use(
session({
key: 'lencamoSessionID',
cookie: {
maxAge: 1000 * 60 * 60
}
})
)
// session✨判断拦截
app.use(async (ctx, next) => {
if (ctx.url.includes('login')) {
await next()
return
}
if (ctx.session.user) {
// 重置过期时间
ctx.session.mydate = Date.now()
await next()
} else {
ctx.redirect('/login')
}
})
app.listen(3000, '127.0.0.1', function () {
console.log('Server running at http://127.0.0.1:3000')
})
- routes/user.js
const Router = require('koa-router')
const router = new Router()
router.post('/login', (ctx, next) => {
const {username, password} = ctx.request.body
if(username==="lencamo" && password==="123"){
// 设置🚩session(随便赋予一个值)
ctx.session.user = {
username: 'lencamo'
}
ctx.body = {
ok: 1
}
}else{
ctx.body = {
ok: 0
}
}
await ctx.render('home', { username: 'lencamo' })
})
module.exports = router
# 2、JWT
总的来说,逻辑上和前面 express 中使用 JWT 是一样的,只是语法上有些许差别罢了(ctx、async/await)。
安装:
npm i jsonwebtoken
使用:
- util/JWT.js
const jwt = require('jsonwebtoken')
const secret = '<秘钥>'
const JWT = {
// 1、生成token字符串
generate(value, expires) {
// 使用sign函数
return jwt.sign(
{
// data: '<数据>'
data: value
},
secret,
{
// expiresIn: '<有效期>'
expiresIn: expires
}
)
},
// 2、解密数据
verify() {
try {
return jwt.verify(token, secret)
} catch (error) {
return false
}
}
}
module.exports = JWT
- index.js
// 🚩校验token的中间件
app.use(async (ctx, next) => {
if (req.url.includes('login')) {
await next()
return
}
// 思考?ES6语法
// const token = req.headers['authorization'] && req.headers['authorization'].split(" ")[1]
const token = ctx.headers['authorization']?.split(' ')[1]
if (token) {
const payload = JWT.verify(token)
if (payload) {
// 重新计算token✨过期时间(以最后一次离开的时间为准)
const newToken = JWT.generate(
{
// 设置要存储到token的数据
_id: payload._id,
username: payload.username
},
'2h'
)
ctx.set('Authorization', newToken)
await next()
} else {
ctx.status(401)
ctx.body = { errCode: -1, errInfo: 'token过期' }
}
} else {
await next()
}
})
- routes/user.js
const Router = require('koa-router')
const router = new Router()
router.post('/login', (ctx, next) => {
const {username, password} = ctx.request.body
if(username==="lencamo" && password==="123"){
// 在服务端设置设置🚩header
const token = JWT.generate({
_id: '65462fdq'
username: 'lencamo'
}, '2h')
// token返回到✨header上
ctx.set('Authorization', token)
ctx.body = {
ok: 1
}
}else{
ctx.body = {
ok: 0
}
}
await ctx.render('home', { username: 'lencamo' })
})
module.exports = router
- views/login.ejs
<head>
<script>
axios.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
// 向服务端发送token✨(校验使用)
const token = localStorage.getItem('token')
config.headers.Authorization = `Bearer ${token}`
return config
},
function (error) {
return Promise.reject(error)
}
)
// 添加响应拦截器
axios.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数
// 客户端接收✨token
console.log(response.headers)
const { authorization } = response.headers
authorization && localStorage.setItem('token', authorization)
return response
},
function (error) {
if (err.response.status === 401) {
localStorage.removeItem('token')
localtion.href = '/login'
}
return Promise.reject(error)
}
)
</script>
</head>
<body>
……
<script>
login.onclick = () => {
aixos
.post('/user/login', {
username: username.value,
password: password.value
})
.then((res) => {
// console.log(res.data)
// console.log(res.headers)
if (res.ok === 1) {
location.href = '/backend'
} else {
alert('用户名密码不匹配!!')
}
})
}
</script>
</body>
# 六、Koa 与 MongoDB 数据库
# 1、安装
npm i mongoose
# 2、连接数据库
- index.js
require('./config/db.config.js')
- 新建:config/db.config.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/ren_db')
# 3、创建集合对应的 MongoDB 模型
- 新建:model/userModel.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const UserType = {
username: String,
password: String,
age: Number
phone: String,
}
// 创建的user模型,会自动对应users集合
const userModel = mongoose.model('user', new Schema(UserType))
module.exports = UserModel
# 4、API 接口
- index.js
const usersRouter = require('./router/usersRouter')
app.use('/api', usersRouter)
- router/usersRouter.js
// 导入user模型(这样就可以🚩使用user.create | user.find | user.delete | user.update来操作数据了)
const UserModel = require('../model/UserModel')
router.post('/user/add', async (ctx) => {
console.log(ctx.request.body)
// ✨前端传来的数据
const { username, password, age, phone } = ctx.request.body
await UserModel.create({
username,
password,
age,
phone
}).then((data) => {
console.log(data)
ctx.body = {
ok: 1
}
})
})