又是一番捣鼓折腾,Fix
的登录
和评论
功能上线了!(暂不支持注册)
当然,过程并非一帆风顺,产生了不少疑问,踩了一些坑。本文记录我在设计这两个模块时的构想和遇到的种种坑。
登录模块
设计构想
起初我把这个模块放在了首页右侧(也就是现在的个性签名位置)。但仔细一想,登录功能除了发评论写留言之外貌似没有其他的用武之地,博客没有必要的登录需求,所以也就没有把这个功能放在显眼位置,只有当用户准备发评论留言的时候才会出现。最后的理想状态是不刷新界面以弹出表单小组件
的形式出现,但因为一些设计需要,暂时把路由设置为了 /login。
填坑
1、login method
先来写个登录请求,照搬老套路,对表单
的用户名密码发出POST
请求。可是问题来了,后端接收不到请求的具体内容。在网上爬了多篇文章后,大致弄清了这个问题出现的原因:
归根结底,不管PHP
、Java
亦或是Node.js
。想要在后台接收到POST
的数据,都需要POST
在发送时使用编码格式application/x-www-form-urlencoded
。浏览器的原生的<form>
表单,如果不设置 enctype 属性,那么最终就会以这种方式提交数据。
然而,Vue.js
推荐使用的 HTTP 库axios
默认的Content-type
设置的为application/json
,通过这种方式发送的数据后台无法通过正常方式获取。解决方法是在nuxt.config.js
的serverMiddleware
属性中加入body-parser
中间件:
serverMiddleware: [
// parse application/json,封装 req.body。
bodyParser.json(),
// API middleware
'~/api/index.js'
]
2、路由跳转
先来设计个admin界面
,设定是只有登录者可见,如果未登录用户直接访问 /admin 则要跳转到 /login。根据Nuxt
的流程图,需要用到middleware
,于是我新建authenticated.js
中间件来帮助我完成这部分操作。同样,也需要在nuxt.config.js
中进行配置。
router: {
middleware: 'authenticated'
}
我们先来实现完成跳转的路由。由于SSR
的特殊性,在判别服务器请求和客户端请求时需要用到不同的方法:
const path = process.server ? req.originalUrl : route.path
if (path.includes('admin')) {
redirect('/login')
}
3、路由鉴权
跳转的路由搞定了,剩下就是鉴权了。根据习惯,后端我用了express-session
中间件。设定完成过期期限,登录成功时录入session
后。回到刚才的middleware
判断req.session
,问题又来了……
if (process.server) {
if (req.session.user) {
let path = req.originalUrl
if (path.indexOf('admin') > 0) {
redirect('/login')
}
}
}
服务器请求好办,客户端请求上下文中没有req
,如何判别登陆状态?
一时没想到什么解决方法,回归官网文档,发现最好的办法是使用Vuex状态树
。刚开始有些头皮发麻,感觉牵扯到 Vuex 的项目都会变得很复杂,尝试后感觉条例还算清晰,实现起来并不复杂,判断 session 在store
中进行。最终完整的判断逻辑如下(store 部分内容省略):
export default function ({ store, req, redirect, route }) { // {} 引用来自 context
if (!store.state.authUser) { // 没有登陆的用户全部重定向到登陆界面
const path = process.server ? req.originalUrl : route.path
if (path.includes('admin')) {
redirect('/login')
}
}
}
评论模块
效果
如本文下方评论所示
填坑
关于评论的数据库存储,起初的构想是存储在article
的表里,每条 article 对应一个 comment,嵌套数组实现,用子文档查询。为了达到高内聚低耦合
的设计理念,我改用了新的存储格式,全部存储在新的comment
表里。因为从最开始就没使用Mongoose框架
,各种手动造轮子,所以在引用的展开上遇到了一些小麻烦。最后给 Mongoose 的 populate() 造了个轮子完美解决。
开源
评论的后端存储结构的演示和转换返回结果已经作为 AraComment 项目在GitHub
开源。
总结
好了,博客的开发到此暂时告一段落,返校学习之余,是时候潜水一波准备4个月后的那场日本语能力测试
了。