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

Odoo14如何实现PDF文件公开URL无需认证即可访问

Odoo14 实现binary字段存储PDF免登录公开访问方案

不需要修改原有PDF生成逻辑,补3部分代码即可实现需求:

    1. 新增公开权限的访问控制器
      Odoo默认的binary字段访问接口会校验用户登录状态,必须自定义auth='public'的路由绕开登录校验,同时加令牌校验防止文件被恶意遍历下载。
      在自定义模块的controllers目录下新建控制器文件,参考代码如下:
from odoo import http
from odoo.http import request, Response
import base64

class PublicPdf(http.Controller):
    @http.route('/public/pdf/<int:record_id>/<string:access_token>', type='http', auth='public', csrf=False)
    def public_pdf_access(self, record_id, access_token, **kwargs):
        # 用sudo()绕过权限校验,同时匹配令牌确认访问合法
        record = request.env['替换为你的业务模型_name值'].sudo().browse(record_id)
        if not record.exists() or record.access_token != access_token:
            return Response("无效访问链接", status=403)
        
        # 解码binary字段存储的base64内容
        pdf_data = base64.b64decode(record.替换为你存PDF的binary字段名)
        # 设置响应头让浏览器直接预览PDF,如果要触发下载就把inline改成attachment
        resp_headers = [
            ('Content-Type', 'application/pdf'),
            ('Content-Disposition', f'inline; filename="{record.文件名 or "报表"}.pdf"')
        ]
        return Response(pdf_data, headers=resp_headers)
    1. 给存储PDF的业务模型增加令牌字段和链接生成方法
      在对应模型的Python代码里新增字段,用UUID做唯一访问令牌,避免ID遍历漏洞,同时写好链接拼接方法:
from odoo import models, fields, api
import uuid

class YourBusinessModel(models.Model):
    _name = '替换为你的业务模型_name值' # 比如sale.order、自定义的my.report等

    # 你之前已经建好的存PDF的binary字段,不用改原有属性
    pdf_report = fields.Binary(string="PDF报表")
    # 新增公开访问令牌字段,设置copy=False避免复制记录时令牌重复
    access_token = fields.Char(string="公开访问令牌", copy=False, index=True)

    # 记录创建时自动生成唯一令牌,也可以在PDF生成完成时再生成
    @api.model
    def create(self, vals):
        record = super().create(vals)
        if not record.access_token:
            record.access_token = str(uuid.uuid4())
        return record

    # 调用这个方法就能拿到完整的公开访问链接
    def get_public_pdf_link(self):
        self.ensure_one()
        if not self.access_token:
            self.access_token = str(uuid.uuid4())
        base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
        return f"{base_url}/public/pdf/{self.id}/{self.access_token}"
    1. 业务逻辑中调用获取链接
      原有PDF生成逻辑不变,在生成完PDF存到binary字段后,直接调用record.get_public_pdf_link()就能拿到可直接访问的公开链接,用户不需要登录就能打开预览。
  • 关键注意点:
    • 绝对不能省略access_token校验逻辑,否则任何人只要遍历ID就能下载所有PDF,存在严重数据泄露风险
    • 控制器路由的auth参数必须设为public,用默认值会强制跳转登录页
    • Odoo的binary字段存的是base64编码内容,返回给前端前必须用base64.b64decode解码,否则打开的PDF会损坏
    • 如果需要做链接过期控制,只要额外加一个链接过期时间字段,在控制器里加时间判断即可

内容的提问来源于stack exchange,提问作者Kholood Al Hitar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:15:17