You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Caveman2动态提供文件并实现权限控制?

在Caveman2中从控制器返回受权限保护的文件

核心实现思路

Caveman2基于Clack开发,底层已经封装了usocket、flexi-streams这类依赖,完全不需要你手动操作socket。直接用Clack标准的响应格式返回文件即可,这是框架的标准用法,不用自己造轮子。

步骤1:先做权限校验(前置逻辑)

在处理文件请求的控制器前,必须先加认证和权限校验,确保只有合法用户能访问:

;; 权限校验中间件
(defun auth-check-middleware (app)
  (lambda (env)
    (let ((current-user (gethash :user (getf env :session)))
          (target-file (getf env :path-info)))
      (if (and current-user (user-can-access-file-p current-user target-file))
          (funcall app env)
          '(403 (:content-type "text/plain") ("无访问权限"))))))

;; 挂载到你的Caveman2应用
(setf *app* (auth-check-middleware *app*))

user-can-access-file-p是你自己实现的函数,用来判断当前用户是否有权限访问目标文件

步骤2:控制器返回文件的标准写法

构造Clack规范的响应三元组(状态码、HTTP头、文件内容),同时设置控制浏览器行为的头信息:

(defroute GET "/protected-files/:filename" (&key filename)
  (let* ((file-full-path (merge-pathnames filename #P"/你的受保护文件目录路径/"))
         (file-exists (uiop:file-exists-p file-full-path)))
    (if (not file-exists)
        '(404 (:content-type "text/plain") ("文件不存在"))
        (let* ((mime-type (trivial-mimes:mime file-full-path))
               (file-content (uiop:read-file-byte-vector file-full-path)))
          `(200
            (:content-type ,mime-type
             :content-length ,(length file-content)
             ;; inline让浏览器直接打开,attachment触发下载,按需切换
             :content-disposition ,(format nil "inline; filename=\"~a\"" filename))
            (,file-content))))))

关键细节说明

  • 依赖补充:需要trivial-mimes自动识别文件MIME类型,执行(ql:quickload :trivial-mimes)即可加载
  • 读取文件用uiop:read-file-byte-vector:这是Common Lisp标准UIOP库的函数,处理二进制文件更稳妥,不用手动操作flexi-streams
  • Content-Disposition的作用:
    • 写inline; filename="xxx.pdf":浏览器直接打开PDF、图片这类文件
    • 写attachment; filename="xxx.pdf":强制触发文件下载
  • 必须返回字节向量:二进制文件不能转成字符串返回,否则会出现乱码

常见问题排查

  • 文件返回乱码:检查是否返回的是byte-vector类型,而非字符串
  • 权限校验不生效:确认会话中用户信息存储正确,user-can-access-file-p逻辑无误

内容的提问来源于stack exchange,提问作者leinad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:57:14