广州城市建设规划局网站,微信小程序商城平台,热门搜索关键词,建设网站花费https://github.com/zep03/koa-coderhub/commits/main 一、coderhub功能接口说明
Coderhub旨在创建一个程序员分享生活动态的平台。 完整的项目接口包括#xff1a;
面向用户的业务接口#xff1b;面向企业或者内部的后台管理接口#xff1b;
完成的功能如下#xff1a;… https://github.com/zep03/koa-coderhub/commits/main 一、coderhub功能接口说明
Coderhub旨在创建一个程序员分享生活动态的平台。 完整的项目接口包括
面向用户的业务接口面向企业或者内部的后台管理接口
完成的功能如下 1.用户管理系统 2.内容管理系统 3.内容评论管理 4.内容标签管理 5.文件管理系统 其他功能其实都是非常相似的
二、项目的搭建
功能一目录结构的划分
按照功能模块划分按照业务模块划分 功能二应用配置信息写到环境变量
编写.env文件通过dotenv加载配置的变量
npm 官方文档的这样介绍 dotenv: Dotenv 是一个零依赖的模块它能将环境变量中的变量从 .env 文件加载到 process.env 中。
功能三创建和启动服务器
基于koa创建app -启动服务器
三、用户注册接口
用户注册接口编写流程
注册用户路由router编写处理函数的控制器controller编写操作数据库的service编写 数据库连接操作mysql2 5. 创建数据库连接 6. 测试数据库连接是否成功
注册用户校验
用户名或密码不能为空 用户名没有被注册过
密码加密存储: 四、用户登录接口
用户登录接口编写流程
授权router的编写处理函数的controller编写 实现动态加载路由
验证的中间件 3. 账号和密码是否为空 4. 用户名是否存在 5. 校验密码是否一致
登录成功返回凭证 6. cookiesession 7. Token令牌
五、为什么需要登录凭证呢 web开发中我们使用最多的协议是http但是http是一个无状态的协议。 无状态的协议什么叫做无状态协议呢 举个例子 我们登录了一个网站 www.coderhub.com当然这个网站不存在是我要开发一个的; 登录的时候我们需要输入用户名和密码比如用户名coderwhy密码Coderwhy666.;
登录成功之后我们要以coderwhy的身份去访问其他的数据和资源还是通过http请求去访问。
coderhub的服务器会问你谁呀coderwhy说我是coderwhy呀刚刚登录过呀coderhub怎么证明你刚刚登录过呀coderwhy说这。。。http没有告诉你吗coderhubhttp的每次请求对我来说都是一个单独的请求和之前请求过什么没有关系。
看到了吧这就是http的无状态也就是服务器不知道你上一步做了什么我们必须得有一个办法可以证明我们登录过。
六、认识cookie
Cookie复数形态Cookies又称为“小甜饼”。类型为“小型文本文件某些网站为了辨别用户身份而存储在用户本地终端Client Side上的数据。
浏览器会在特定的情况下携带上cookie来发送请求我们可以通过cookie来获取一些信息
Cookie总是保存在客户端中按在客户端中的存储位置Cookie可以分为内存Cookie和硬盘Cookie。
内存Cookie由浏览器维护保存在内存中浏览器关闭时Cookie就会消失其存在时间是短暂的硬盘Cookie保存在硬盘中有一个过期时间用户手动清理或者过期时间到时才会被清理
如何判断一个cookie是内存cookie还是硬盘cookie呢
没有设置过期时间默认情况下cookie是内存cookie在关闭浏览器时会自动删除有设置过期时间并且过期时间不为0或者负数的cookie是硬盘cookie需要手动或者到期时才会删除
七、cookie常见的属性
cookie的生命周期
默认情况下的cookie是内存cookie也称之为会话cookie也就是在浏览器关闭时会自动被删除我们可以通过设置expires或者max-age来设置过期的时间 expires设置的是Date.toUTCString()设置格式是;expiresdate-in-GMTString-format max-age设置过期的秒钟;max-agemax-age-in-seconds (例如一年为60*60*24*365)
cookie的作用域允许cookie发送给哪些URL
Domain指定哪些主机可以接受cookie
如果不指定那么默认是 origin不包括子域名。如果指定Domain则包含子域名。例如如果设置 Domainmozilla.org则 Cookie 也包含在子域名中如developer.mozilla.org。
Path指定主机下哪些路径可以接受cookie 例如设置 Path/docs则以下地址都会匹配 /docs /docs/Web/ /docs/Web/HTTP
八、客户端设置cookie
js直接设置和获取cookie
这个cookie会在会话关闭时被删除掉 设置cookie同时设置过期时间默认单位是秒钟
九、服务器设置cookie
Koa中默认支持直接操作cookie
/test请求中设置cookie/demo请求中获取cookie 十、Session是基于cookie实现机制
在koa中我们可以借助于 koa-session 来实现session认证
设置secrets加密字符串用于加密数据
十一、认识token
cookie和session的方式有很多的缺点
Cookie会被附加在每个HTTP请求中所以无形中增加了流量事实上某些请求是不需要的Cookie是明文传递的所以存在安全性的问题Cookie的大小限制是4KB对于复杂的需求来说是不够的对于浏览器外的其他客户端比如iOS、Android必须手动的设置cookie和session对于分布式系统和服务器集群中如何可以保证其他系统也可以正确的解析session
所以在目前的前后端分离的开发过程中使用token来进行身份验证的是最多的情况
token可以翻译为令牌也就是在验证了用户账号和密码正确的情况给用户颁发一个令牌这个令牌作为后续用户访问一些接口或者资源的凭证我们可以根据这个凭证来判断用户是否有权限来访问
所以token的使用应该分成两个重要的步骤
生成token登录的时候颁发token验证token访问某些资源或者接口时验证token
十二、JWT实现Token机制 JWT生成的Token由三部分组成
header
alg采用的加密算法默认是 HMAC SHA256HS256采用同一个密钥进行 加密和解密typJWT固定值通常都写成JWT即可会通过base64Url算法进行编码
payload
携带的数据比如我们可以将用户的id和name放到payload中默认也会携带iatissued at令牌的签发时间我们也可以设置过期时间expexpiration time会通过base64Url算法进行编码
signature
设置一个secretKey通过将前两个的结果合并后进行HMACSHA256的算法HMACSHA256(base64Url(header).base64Url(payload), secretKey);但是如果secretKey暴露是一件非常危险的事情因为之后就可以模拟颁发token也可以解密token
十三、Token的使用
当然在真实开发中我们可以直接使用一个库来完成 jsonwebtoken
十四、非对称加密
前面我们说过HS256加密算法一单密钥暴露就是非常危险的事情
比如在分布式系统中每一个子系统都需要获取到密钥那么拿到这个密钥后这个子系统既可以发布另外也可以验证令牌但是对于一些资源服务器来说它们只需要有验证令牌的能力就可以了
这个时候我们可以使用非对称加密RS256
私钥private key用于发布令牌公钥public key用于验证令牌
我们可以使用openssl来生成一对私钥和公钥
Mac直接使用terminal终端即可Windows默认的cmd终端是不能直接使用的建议直接使用git bash终端 十五、使用公钥和私钥签发和验证签名 注意
const Koa require(koa)
const Router require(koa-router)
const jwt require(jsonwebtoken)
const fs require(fs)
const path require(path)const app new Koa()
const testRouter new Router()const PRIVATE_KEY fs.readFileSync(path.join(__dirname, ./keys/private.key));
const PUBLIC_KEY fs.readFileSync(path.join(__dirname, ./keys/public.key));// 登录接口
testRouter.post(/test, (ctx, next) {const user {id: 110, name: zep}const token jwt.sign(user, PRIVATE_KEY,{expiresIn: 60 * 60,algorithm: RS256})ctx.body token
})// 验证接口
testRouter.get(/demo, (ctx, next) {const authorization ctx.headers.authorizationconst token authorization.replace(Bearer , )try {const result jwt.verify(token, PUBLIC_KEY, {algorithm: [RS256]})ctx.body result} catch (err) {console.log(err.message)ctx.body err.message}
})app.use(testRouter.routes())app.listen(8001, (err) {console.log(服务器启动成功)
}) 十六、派发令牌和验证令牌 postman中设置全局变量token:
十七、发布和查询动态内容
创建新的表 moment
定义发布动态内容的接口
定义路由接口验证用户登录Controller和Service中处理内容 定义查询单个内容的接口
根据momentId查询接口内容 SELECT m.id, m.content, m.createAt, m.updateAt as updateTime,
JSON_OBJECT(id, u.id, name, u.name) as user
FROM moment as m
left join user as u on m.user_id u.id
where m.id 1 定义查询多条内容的接口
查询所有moment接口内容根据offset和limit决定查询数量 十八、修改和删除动态内容
定义修改动态内容的接口
定义路由接口验证用户登录验证用户的权限Controller和Service中的处理 定义删除内容的接口
定义路由接口验证用户登录验证用户权限Controller和Service的处理 十九、发表和修改评论内容 注意 关系表的级联更新 on update cascade on delete cascade 是级联删除的意思 意思是 当你更新或删除主键表时那么外键表也会跟随一起更新或删除
创建新的表 comment 定义发布评论内容的接口
定义路由接口验证用户登录Controller和Service中处理内容 回复评论接口 定义修改评论内容的接口
定义路由接口验证用户登录验证用户的权限Controller和Service中的处理
二十、删除和查询评论内容
定义删除评论内容的接口
定义路由接口验证用户登录验证用户权限 p Controller和Service的处理 查询动态的时候同时显示评论信息
查询多个动态时显示评论的个数 查询单个动态时显示评论的列表 根据动态的id获取评论详情 二十一、标签接口开发 创建标签的表
定义创建标签接口
路由配置Router验证用户登录创建标签 创建标签和动态关系表
定义给动态添加标签的接口
给动态添加新的接口 查询所有标签列表 查询标签接口
查询动态列表展示标签数量 根据动态id展示标签列表 二十二、上传头像图片 上传头像逻辑
定义上传图像的接口定义获取图像的接口请求用户信息时获取头像
分析实现思路
1.图片文件上传 /upload/avatar 目的服务器端可以保存一张图片2.提供一个接口可以让用户获取图片 /1/avatar - 找到图片\读取图片\content-type: image/jpeg\返回图像的信息3.将URL存储到用户信息中 avatarURL: 头像的地址4.获取信息时获取用户的头像
1. 定义上传图像的接口将用户上传的图片保存到服务器本地的uploads/avatar文件夹下然后再把图片的信息保存到数据库中的avatar表中 2. 定义获取图像的接口 3. 请求用户信息时获取头像 3.1 修改上传头像接口不仅要把上传的头像信息保存到数据库的avatar表中还要将上传的用户头像的avatarUrl保存到数据库的用户表中 3.2 修改原来的动态查询接口增加avatarUrl字段 二十三、上传动态的配图 上传动态配图
定义上传动态配图的接口定义获取动态配图的接口获取动态时获取配图信息 1. 定义上传动态配图的接口 2. 定义获取动态配图的接口 3. 获取动态时获取配图信息
根据momentId获取动态的配图
附加处理上传的图片将图片分成三种大小 JavaScript 编写的图像处理库 Jimphttps://github.com/oliver-moran/jimp https://github.com/oliver-moran/jimp/tree/master/packages/plugin-resize 然后修改获取动态配图的接口