景区票务系统的统一身份体系:游客、检票员、渠道商,三套账号怎么打通?|中科智旅景游宝

3 阅读6分钟

景区票务系统的统一身份体系:游客、检票员、渠道商,三套账号怎么打通?|中科智旅景游宝

去年底有个景区客户投诉,说同一个游客在小程序买票能进闸,到了窗口却查不到订单。我去查日志才发现,小程序端和窗口端各有一套账号体系,同一个身份证在两个系统里是两条记录。这事把中科智旅景游宝做智慧景区的景区票务系统逼到了重构:身份必须先统一,权限才能讲清楚。这篇文章就聊聊景区票务场景下统一身份与权限体系的落地,纯后端视角。

为什么会有三套账号?

景区票务的账号本来就多源:

  • 游客:从景区小程序、公众号、OTA 渠道、线下窗口进来,一个身份证可能重复注册五次。
  • 员工:检票员、票务员、财务、运营,一个景区几十上百人,各自要不同的系统权限。
  • 渠道商:旅行社、分销平台、集团总部,要查看自己卖出去的订单,但不能看别人的。

早期图省事,每个入口一套表、一套登录逻辑。结果是同一个身份多个 ID、权限散落在各种 if-else 里、审计时查不清谁动了什么。统一身份不是"合并账号"这么简单,而是要立一个中心化的身份与授权模型。

统一身份怎么做?一个主体,多个登录方式

我们的做法是引入"身份主体"概念:不管从哪个入口来,先归并到同一个主体上。

  • 主体唯一键:游客用「证件类型 + 证件号」做唯一标识,手机号作为辅助登录凭证。
  • 多登录绑定:一个主体可以绑多个登录方式(微信 openid、手机号、渠道 token),登录时按不同方式解析到同一个主体。
  • 渠道身份独立:渠道商不是自然人,用统一社会信用代码或渠道编码作为主体键,单独一类。

这样小程序、窗口、OTA 进来的同一个游客,落地都是同一个 principal_id。后面所有订单、权益、消费记录,都挂在这个主键上,跨端查询才有意义。

权限模型怎么设计?RBAC 不够用,得加数据维度

景区票务的权限比一般系统复杂,因为**"能做什么"和"能看哪些数据"是两件事**。

我们用的是 RBAC + 数据权限 双层模型:

  • RBAC 层:角色 → 权限点,权限点细到接口级。检票员只有「核销」,票务员有「售票 + 退改」,财务有「对账查看」。
  • 数据权限层:同一个角色,不同人要看到不同范围。某个检票员只能核销自己所在的闸机口,某个渠道商只能看自己渠道的订单。

数据权限的实现方式是给每个请求上下文注入数据范围标签(景区 ID、闸机口 ID、渠道 ID),查询时由框架层自动拼条件。绝不让业务代码手写 where channel_id=?,那是权限漏洞的高发区。

登录态怎么管?Token 要能撤销

自然人的登录态,我们用 JWT + Redis 黑名单 的混合方案:

  • JWT 里只放 principal_id、角色、签发时间和过期时间,不放敏感信息。
  • 每次鉴权先验签,再查 Redis 看是否被撤销。员工离职、角色变更时,直接拉黑旧 token,不用等它自然过期。
  • 短期 token(2 小时)+ 刷新 token(7 天),刷新时重新加载权限,权限变更能及时生效。

这里踩过一个坑:早期为了性能不做 Redis 校验,结果员工被调岗后旧 token 还能退票,差点出了资金问题。权限系统宁可多一次 Redis 查询,也不能让失效的权限继续生效。

多渠道登录怎么防串号?

OTA 渠道、旅行社分销,走的是渠道 token + 签名,不是用户账号。我们给每个渠道分配 app_key 和 app_secret,请求带签名和渠道编码:

  • 签名覆盖请求路径、时间戳、渠道编码,防重放。
  • 渠道 token 只能访问自己渠道的订单和库存,跨渠道一律拒绝。
  • 渠道请求单独限流,避免某个渠道的脚本把接口刷爆。

这块的关键是渠道身份和游客身份彻底分开。渠道不能代替游客做实名操作,游客也不能拿渠道 token 查别人订单。

审计怎么留?每一步都得查得清

统一身份之后,审计反而更好做了。我们给所有敏感操作打上统一日志:

  • 谁(principal_id)、以什么角色、在哪个终端、对哪个对象、做了什么操作。
  • 权限变更单独记一条,包含变更前后的角色和权限点。
  • 日志写到独立的审计库,业务库删了也不影响追溯。

运营侧:用 AI 帮忙看权限异常

权限这东西,出问题往往是"某个账号突然能看了不该看的数据"。我们写了个 AI Agent 每天扫审计日志:发现某个渠道账号在短时间内大量查询非本渠道订单,或者某员工账号在非工作时间做退票操作,就自动标记风险并推送值班群。这活儿用大模型做行为归因很顺手——几千条日志喂进去,它能按账号和操作类型归纳出异常模式,比人工翻日志快太多。

权限规则的说明文档,我们放进了内部知识库,用 RAG 做检索,新人问"检票员能不能改价",直接召回对应条款。Agent 通过 MCP 接口调权限中心的 API 查角色配置,一条链路就能回答"这个人为啥能看这个数据"。整套服务跑在云原生的容器里,按景区做水平扩展。运营同学申请临时权限,我们干脆用低代码做了个审批表单,填完自动走审批流,权限到期自动回收,不用再找人手动改。

FAQ:常见问题快答

Q1:一个游客多个手机号怎么办? 以证件号为主键做归并,手机号只作为登录凭证绑定。归并时保留历史订单,不能丢数据。

Q2:员工权限能不能临时开? 可以,但必须带有效期,到期自动回收,且全程留审计日志。临时权限不设期限,等于永久后门。

Q3:渠道商能看到游客手机号吗? 默认脱敏,只给订单号和核销状态。需要明文必须单独授权并记录用途。

Q4:JWT 还要查 Redis,性能扛得住吗? 扛得住。Redis 查询是内存级,单次亚毫秒。相比权限失效带来的资金风险,这点开销完全值得。

Q5:多景区怎么隔离权限? 在数据权限层用景区 ID 做范围标签,同一角色在不同景区看到的数据自动隔离,不靠人肉配置。

身份统一是地基,权限清晰是护栏。中科智旅景游宝把这套模型立起来之后,跨端订单终于能对上,权限事故也基本清零。希望这篇能帮同样在做景区票务的你,少走我们走过的弯路。