
如何在 Vitepress 中实现权限管理?
在WEB应用中,权限一般是指控制路由或者文档部分内容有权限才可见,确保只有授权的用户能访问特定的功能与数据。
整体思路就两步:
- 先把文档保护起来,不让公开访问。
- 对私有文档做授权,有权限才可见。
文档权限控制,在一些内部私有文档的场景,很有用。
前言
对于使用 Vitepress 构建的项目文档站来说,实现权限管理也是可以实现的。
要在 Vitepress 中实现权限管理,首先得对它的架构和工作原理有个清晰的认识。Vitepress 是一个基于 Vite + Vue
的静态网站生成器,完全可以当成一个前端项目来按需改造。
做权限管理,这里假设你服务端已经有一套用户体系,也已经实现了用户登录功能。也可以参考 Vitepress 微信授权登录
一、保护私有内容
在做权限控制前,先要确定是怎样的机制保护内容前端不可见的。
然后通过授权的方式,在你的保护机制上开个口子给授权的用户访问。
提供两个我都尝试过的方案,可以按这个思路自行选择改造。
方案1:编译时加密
前端的方案,在编译时,使用Vite插件,实现内容的加密,前端判断权限后根据会话取秘钥做解密。
这个功能的Vite插件我没找到开源的,有尝试过自己写,确定是可以实现的。
开发Vite插件:docs/.vitepress/crypto-plugin.js
function cryptoPlugin() {
return {
name: 'crypto-plugin',
enforce: 'pre', // 插件顺序,在Vite核心插件前执行
transform(src, id) {
//id:文件名,判断要处理的文件
if (id.indexOf('.md') !== -1){
//Markdown中的文字加密后,放到解密函数的参数中
//TODO 这部分我已验证了替换的可行性,还差写个加密解密
return src.replace('原文', '处理过的密文')
}
},
};
}
export default cryptoPlugin
使用插件:docs/.vitepress/config.js
import {defineConfig} from 'vitepress'
import cryptoPlugin from './crypto-plugin.js'
export default defineConfig({
vite: {
plugins: [
cryptoPlugin()
]
},
})
方案2:服务端判断
服务端方案,自己开发静态文件服务端,根据请求路径判断当前用户是否有权限,有权限才返回文件内容。
由服务端判断,前端就不用做处理,下面是我用Golang写的例子:
// HandlerStaticServer 静态文件服务
func (ctl *Controller) HandlerStaticServer(ctx *gin.Context) {
path := ctx.Request.URL.Path
if strings.HasSuffix(path, "/") {
path += "/index.html"
}
dir := "/usr/www" // 静态文件根目录,VitePress编译后的文件放这,代替Nginx
fBytes, err := os.ReadFile(dir + path)
if err != nil {
http.NotFound(ctx.Writer, ctx.Request)
return
}
// 请求文件后缀
suffix := (strings.Split(path, "?")[0])[strings.LastIndex(path, "."):]
if suffix == ".html" || suffix == ".js" {
//登录会话
token, _ := hgin.GetCookieToken(ctx)
//已登录,则判断path权限
if token!="" {
//TODO 判断当前用户path权限...
}
}
// 根据文件取Content-Type
contentType := declareContentType[suffix]
if contentType == "" {
contentType = http.DetectContentType(fBytes) //根据内容取Content-Type,优先使用自己声明的
}
ctx.Data(http.StatusOK, contentType, fBytes)
}
用其他语言思路也一样,整体思路就是不使用公开的静态文件服务,而是自己写一个静态文件服务,去判断访问权限。
二、路由页面权限
路由页面权限控制,在路由更新事件监听中实现权限判断
主题入口文件docs/.vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme';
export default {
extends: DefaultTheme,
enhanceApp({app, router}) {
// 单页面应用路由更新时触发事件
router.onBeforeRouteChange = (to) => {
// 根据路由结合后台接口做判断
...
}
}
}
三、文档部分内容权限
通过自定义标签,把需要权限的内容,放到标签中。 可以参考 VitePress会员主题 方案。
总结
这篇文章介绍了在 Vitepress 中实现权限管理的方案,从文档保护与权限判断两个层面做了介绍。