当前位置: 首页 > article >正文

从Auth0迁移到开源Logto:我的真实踩坑与配置心得(多租户场景实践)

从Auth0迁移到开源Logto多租户场景下的实战指南当我们的SaaS产品用户突破10万时Auth0的账单突然变成了财务会议上最刺眼的数字。作为技术负责人我花了三个月评估各种开源身份认证方案最终选择Logto完成迁移。这篇文章将分享从商业服务切换到开源系统的完整历程特别是多租户场景下的配置细节和那些文档里没写的坑。1. 为什么选择Logto替代Auth02019年我们刚开始构建产品时Auth0的开发者友好性让它成为不二之选。但随着业务增长三个核心问题逐渐浮现成本问题MAU超过5万后Auth0企业版报价每年超过$15万定制限制品牌化登录页需要额外付费多租户权限流难以深度定制数据主权欧洲客户强烈要求用户数据留在本地数据中心在对比了Keycloak、Ory Hydra和Logto后我们被Logto的几项特性吸引特性LogtoAuth0企业版Keycloak多租户隔离✅✅❌自定义CSS无限制付费功能需要开发数据导出API全量分批限制全量会话管理粒度应用级全局领域级特别值得一提的是Logto的租户资源隔离设计。在Auth0中不同客户共享同一个用户池仅靠元数据metadata区分租户。而Logto的租户模型更接近AWS的Account隔离每个租户拥有独立的用户目录角色权限体系OAuth应用配置审计日志空间这种架构让我们能为医疗行业的客户提供完全物理隔离的部署方案这在合规谈判时成了关键筹码。2. 迁移前的关键准备工作2.1 数据迁移策略设计我们从Auth0导出数据时遇到了第一个坑——官方导出工具会丢失第三方身份提供者如Google登录的原始ID。这意味着直接导入Logto后用户会无法通过社交账号登录。最终采用的解决方案# 使用Auth0 Management API提取完整身份信息 auth0 login --scopes read:users read:user_idp_tokens auth0 users export --format json --include_fields identities users.json # 使用jq处理数据格式适配Logto cat users.json | jq [.[] | { id: .user_id, name: .name, email: .email, identities: (.identities | map({ provider: .provider, id: .user_id, accessToken: .access_token, refreshToken: .refresh_token })) }] transformed.json注意Auth0的access_token有效期通常只有几小时建议在迁移窗口期操作2.2 会话兼容性测试Auth0默认使用HS256算法签名JWT而Logto默认使用RS256。我们提前两周在测试环境部署了以下兼容层location /auth { proxy_pass http://logto:3001; # 转换JWT算法标识头 proxy_set_header X-JWT-Algorithm HS256; # 保持相同的cookie名称 proxy_cookie_domain logto-test.example.com auth.example.com; }这个配置让客户端应用无需立即修改代码就能继续工作为前端团队争取了迭代时间。3. 多租户配置的实战细节3.1 租户资源拓扑设计Logto的租户系统支持树状结构我们根据业务需求设计了三级模型1. 平台级资源 - 超级管理员控制台 - 跨租户分析报表 2. 组织级租户 (对应企业客户) - 自定义域名: clientX.app.example.com - 独立用户目录 - 品牌化登录页 3. 项目级空间 (组织内子单元) - 细粒度权限组 - 应用间单点登录配置示例通过Logto Admin API实现// 创建组织级租户 fetch(https://logto-core/admin/api/tenants, { method: POST, headers: { Authorization: Bearer ${adminToken} }, body: JSON.stringify({ name: Acme Corp, customDomains: [acme.app.example.com], parentTenantId: null // 顶级租户 }) }); // 创建项目级空间 fetch(https://logto-core/admin/api/tenants, { method: POST, body: JSON.stringify({ name: Project Phoenix, parentTenantId: acme-tenant-id, quota: { monthlyActiveUsers: 500, storageGB: 10 } }) });3.2 跨租户权限管理Auth0的RBAC在跨租户场景下表现不佳经常需要编写复杂的规则Rules。在Logto中我们利用资源API作用域的组合实现了更灵活的管控在平台级定义基础资源类型resources: - key: storage name: Object Storage scopes: - storage:read - storage:write - storage:admin为每个租户创建资源实例curl -X POST https://logto-core/admin/api/resources \ -H Authorization: Bearer $TENANT_TOKEN \ -d { key: storage:acme-prod, name: Acme Production Storage, parentResource: storage }通过条件策略动态授权-- Logto策略SQL模板 SELECT 1 FROM tenant_memberships WHERE user_id {{.context.user.id}} AND tenant_id {{.resource.tenantId}} AND role storage-admin这套机制让我们实现了平台管理员可以访问所有租户的审计日志租户管理员只能管理本组织内的用户项目成员仅看到所属空间的资源4. 那些官方文档没告诉你的坑4.1 社交登录的域名验证陷阱当尝试为租户配置自定义域名的Google OAuth时我们发现Auth0允许在同一个顶级域下共享验证如 *.app.example.comGoogle开发者控制台需要显式注册每个子域名Logto的社交登录回调URL必须精确匹配解决方案是开发一个域名验证代理app.route(/auth/google/tenant) def google_auth_proxy(tenant): tenant_domain get_tenant_domain(tenant) if not current_user.has_access_to(tenant): abort(403) redirect_uri fhttps://{tenant_domain}/callback return redirect( fhttps://logto-core/connectors/google?redirect_uri{quote(redirect_uri)} )4.2 会话并发控制的特殊处理Auth0默认允许5个并发会话而Logto的会话管理更严格。某个客户突然出现大量会话失效投诉最终发现是他们团队共享测试账号导致。我们在Logto的中间件层添加了特殊处理// 针对测试账号放宽限制 app.use(async (ctx, next) { if (ctx.path /session ctx.user.email.endsWith(test.acme.com)) { ctx.session.maxAge 86400 * 30 // 30天有效期 ctx.session.concurrentLimit 20 } await next() })4.3 审计日志的性能优化当审计日志表超过1000万条时查询性能急剧下降。我们采用以下优化组合冷热数据分离CREATE TABLE audit_logs_current PARTITION OF audit_logs FOR VALUES FROM (2023-10-01) TO (2023-11-01); CREATE TABLE audit_logs_archive PARTITION OF audit_logs FOR VALUES FROM (MINVALUE) TO (2023-10-01);租户级分片索引logto-cli index create --table audit_logs \ --columns tenant_id,created_at \ --where tenant_id IS NOT NULL异步写入队列func (s *AuditService) Log(event AuditEvent) { select { case s.queue - event: // 异步处理 default: metrics.Increment(audit_queue_dropped) } }迁移完成后我们的认证系统成本降低82%客户定制需求实现周期从平均2周缩短到3天。最意外的是由于可以深度集成到客户网络环境某医疗客户因此与我们签订了3年的框架协议。

相关文章:

从Auth0迁移到开源Logto:我的真实踩坑与配置心得(多租户场景实践)

从Auth0迁移到开源Logto:多租户场景下的实战指南 当我们的SaaS产品用户突破10万时,Auth0的账单突然变成了财务会议上最刺眼的数字。作为技术负责人,我花了三个月评估各种开源身份认证方案,最终选择Logto完成迁移。这篇文章将分享从…...

别再死磕Altera了!用AG10KSDE176国产FPGA做个LED灯牌控制器,成本直降一半

低成本LED灯牌控制器实战:国产FPGA AG10KSDE176替代方案详解 在创客圈子里,LED灯牌和灯屏项目一直是个热门话题。从简单的文字滚动到复杂的动画效果,FPGA因其并行处理能力和灵活的可编程特性,成为这类项目的理想选择。然而&#x…...

从I2C到SMBus:搞懂新版Spec 3.3,别再傻傻分不清了(附对比表格)

从I2C到SMBus:搞懂新版Spec 3.3,别再傻傻分不清了(附对比表格) 在嵌入式系统和硬件设计领域,I2C和SMBus这两种看似相似却又各具特色的总线协议常常让工程师们陷入选择困境。特别是在电源管理、温度监控等关键系统中&am…...

Vibe Coding:跟电脑「聊天」就能写代码

Vibe Coding:跟电脑「聊天」就能写代码📌 导读:想象你跟电脑说「帮我写一个记账 App」,然后代码就出来了——这不是科幻,这是 Vibe Coding。2025 年这个词火遍全球,连 OpenAI 联合创始人都说「我已经彻底停…...

自动驾驶感知入门:用Python手把手实现CTRV模型与EKF/UKF滤波(附代码避坑)

自动驾驶感知实战:CTRV运动模型与EKF/UKF的Python实现指南 在自动驾驶系统的感知模块中,目标跟踪的准确性直接影响着路径规划与决策的质量。当我们面对城市道路中频繁变道、加减速的车辆时,传统的匀速(CV)模型往往力不从心。本文将带您从零实…...

3个简单步骤:完美实现Windows任务栏透明美化终极方案

3个简单步骤:完美实现Windows任务栏透明美化终极方案 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 想要让Windows桌面焕然一…...

【AI配音生产力革命】:2026奇点大会验证的4类可商用模型对比——时延<200ms、情感准确率≥91.7%、版权链上存证

第一章:2026奇点智能技术大会:AI配音应用 2026奇点智能技术大会(https://ml-summit.org) 实时语音克隆与情感注入技术突破 本届大会首次公开演示了基于多模态对齐的零样本语音克隆框架VoiceSynth-X,该框架仅需3秒参考音频即可生成高保真、带…...

会议效率提升300%的秘密:SITS2026认证的“语境锚定+角色意图识别”双引擎纪要生成范式

第一章:SITS2026专家:AI会议纪要生成 2026奇点智能技术大会(https://ml-summit.org) 核心能力定位 SITS2026专家系统专为高保真、可追溯、结构化会议纪要生成而设计,深度融合语音识别(ASR)、多轮对话理解&#xff08…...

Hyperf对接报表 在 HyperF 中集成帆布报表时,如何利用 Redis 缓存机制对报表模板和查询结果进行分级缓存?请说明缓存失效策略的设计思路及其对业务的影响。

选型: hyperf/cache(注解驱动) hyperf/redis(连接池) predis 不需要,直接用 Swoole 原生 Redis 协程客户端。---缓存分级架构 …...

Hyperf对接报表 企业级报表系统中,针对百万级数据量的帆布报表导出场景,请从 HyperF 的进程模型、内存管理、分页查询三个维度,设计一套完整的性能优化方案。

核心选型: openspout/openspout — 流式写入,内存恒定 ~10MB,无需加载整个文档到内存。---架构总览 HTTP请求 → 异步队列 …...

Whisper-WebUI:5分钟让视频创作者告别繁琐字幕制作

Whisper-WebUI:5分钟让视频创作者告别繁琐字幕制作 【免费下载链接】Whisper-WebUI A Web UI for easy subtitle using whisper model. 项目地址: https://gitcode.com/gh_mirrors/wh/Whisper-WebUI 还在为视频字幕制作头疼吗?🎬 每次…...

猫抓浏览器插件:三步搞定网页视频音频下载的终极指南

猫抓浏览器插件:三步搞定网页视频音频下载的终极指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓(Cat-Catch&#…...

内容创作者利器:用HY-MT1.5-7B批量翻译多语言文章

内容创作者利器:用HY-MT1.5-7B批量翻译多语言文章 1. 为什么内容创作者需要专业翻译工具 1.1 多语言内容的市场需求 在全球化内容创作时代,单一语言的内容已经无法满足受众需求。数据显示,多语言内容能带来: 受众覆盖范围扩大…...

项目上传github仓库(flutter)

自用记录 有问题别骂我!真小白! 首先github 新建仓库 填个名字 其他都可以不改 接着项目文件夹 终端运行git init 会生成.gitignore 改成下面的 # Flutter / Dart .dart_tool/ .packages .pub/ build/ .idea/ *.iml *.ipr *.iws .metadata# Window…...

【AI写作生产力跃迁临界点】:2026奇点大会首次披露的“认知对齐度”评估模型(附可落地的5维打分表)

第一章:【AI写作生产力跃迁临界点】:2026奇点大会首次披露的“认知对齐度”评估模型(附可落地的5维打分表) 2026奇点智能技术大会(https://ml-summit.org) “认知对齐度”(Cognitive Alignment Score, CAS&#xff0…...

C#怎么使用TopLevel顶级语句 C#顶级语句怎么写如何省略Main方法简化控制台程序【语法】

TopLevel 语句必须放在项目中唯一一个 .cs 文件里,且该文件不能包含任何 namespace、class、struct 等顶层类型声明;编译器将整个文件视为 Main 方法体处理。TopLevel 语句必须放在哪个文件里只能在项目中唯一一个 .cs 文件里写 TopLevel 语句&#xff0…...

如何突破Cursor设备限制?机器ID重置终极方案详解

如何突破Cursor设备限制?机器ID重置终极方案详解 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial re…...

保姆级教程:手把手教你编译DataX,让它完美支持MySQL 8.0(含常见编译报错解决)

从零构建DataX适配MySQL 8.0全流程实战指南 最近在帮客户做数据迁移时,发现DataX官方版本对MySQL 8.0的支持存在一些兼容性问题。经过几天的折腾,终于成功编译出了完美适配MySQL 8.0的DataX版本。本文将完整记录整个编译过程,包括可能遇到的坑…...

移远EC600S-CN AT指令HTTP实战:手把手教你用QCOM_V1.6调试工具连接OneNET(含串口工具换行符避坑)

移远EC600S-CN AT指令HTTP开发实战:从工具配置到OneNET云平台对接全解析 在物联网设备开发中,HTTP协议作为最常用的应用层协议之一,其稳定性和易用性备受开发者青睐。移远通信的EC600S-CN模块凭借其出色的网络连接能力和丰富的AT指令集&#…...

SENT协议解析:从脉冲信号到精准数据的汽车传感器通信

1. SENT协议:汽车传感器的"摩斯密码" 第一次接触SENT协议时,我盯着示波器上那些密密麻麻的脉冲波形,感觉就像在看天书。但当我真正理解它的工作原理后,才发现这个看似简单的协议设计得如此精妙。SENT(Single…...

ArcGIS水文分析实战:基于高精度DEM构建数字河网

1. 为什么需要从DEM数据提取数字河网? 在野外考察或区域规划时,经常会遇到一个头疼的问题:手头没有现成的水系数据。传统的水文测绘不仅成本高,而且更新周期长。我去年在云南做生态调查时就深有体会——当地最新的水文图还是10年前…...

PHP SAAS 框架常见问题——配置问题——修改 icon 图标

修改 icon 图标 问题: 想修改浏览器标签页的 icon 图标 解决办法: 服务器环境可以直接修改编译包,修改 niucloud/public/admin 下的 ico 文件。无需编译,修改完成后,强刷浏览器页面即可生效 注意:修改的…...

5步快速上手网盘直链下载助手:八大平台高效文件获取指南

5步快速上手网盘直链下载助手:八大平台高效文件获取指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天…...

终极解决方案:如何用CardEditor卡牌生成器30分钟搞定100张桌游卡牌?

终极解决方案:如何用CardEditor卡牌生成器30分钟搞定100张桌游卡牌? 【免费下载链接】CardEditor 一款专为桌游设计师开发的批处理数值填入卡牌生成器/A card batch generator specially developed for board game designers 项目地址: https://gitcod…...

解锁八大网盘全速下载:LinkSwift直链获取工具深度解析

解锁八大网盘全速下载:LinkSwift直链获取工具深度解析 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…...

148:AI产品订阅模式设计——可持续订阅收入模型与续费优化策略

作者: HOS(安全风信子) 日期: 2026-4-02 主要来源平台: GitHub 摘要: 本文深入探讨AI产品的订阅模式设计,通过分析3个成功案例,详细拆解如何设计可持续的订阅收入模型、优化续费策略、提高客户留存率。结合…...

5分钟轻松搞定!Axure RP全系列中文汉化终极指南

5分钟轻松搞定!Axure RP全系列中文汉化终极指南 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文…...

本文是《销量预测准确率98%?我用LightGBM+XGBoost集成在Kaggle拿到Top 1%》的续篇,聚焦模型从Jupyter Notebook走向生产环境的自动化部署与可观测性。包含完整Do

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...

如何3分钟从视频中智能提取PPT:终极自动化工具指南

如何3分钟从视频中智能提取PPT:终极自动化工具指南 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 你是否曾经花费数小时手动暂停视频、截图PPT页面?extract-…...

ruoyi-vue 官网介绍和要点CSMD说明

创建数据库及数据表添加CSMD 相关文件代码:Controllerpackage com.ruoyi.web.controller.system;import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.system.domain.User; import com.ruoyi.system.service.impl.UserService; import org.s…...