# lua-resty-oauth2 **Repository Path**: xtlyk/lua-resty-oauth2 ## Basic Information - **Project Name**: lua-resty-oauth2 - **Description**: 基于 OpenResty Lua 的 OAuth 鉴权平台(企业微信、飞书、钉钉) - **Primary Language**: Lua - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-11-03 - **Last Updated**: 2025-11-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 🔐 lua-resty-oauth2 [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![OpenResty](https://img.shields.io/badge/OpenResty-1.27.1-brightgreen.svg)](https://openresty.org/) [![Lua](https://img.shields.io/badge/Lua-5.1-blue.svg)](https://www.lua.org/) 基于 OpenResty Lua 的企业级 OAuth 2.0 鉴权插件,支持企业微信、飞书、钉钉等主流协同办公平台的统一认证。 [中文文档](README.md) | [English](README_EN.md) ## ✨ 特性 - 🚀 **高性能**:基于 OpenResty,充分利用 Nginx 的异步非阻塞特性 - 🔌 **可插拔**:采用模块化设计,轻松扩展新的 OAuth 提供商 - 🛡️ **安全可靠**:采用 JWT Token + HMAC-SHA256 签名,支持 HTTPS - 🎨 **美观界面**:内置精美的登录页面,支持 SVG 图标 - 🌍 **多语言支持**:自动识别浏览器语言,支持中文(简繁体)和英文,可手动切换 - ⚙️ **易于配置**:简单的配置文件,快速集成到现有项目 - 📝 **详细日志**:完整的调试日志,方便问题排查 ## 项目截图 ![登录页面](images/login.png) ![日志](images/log.png) ## 🏗️ 架构设计 采用标准的 OAuth 2.0 授权码流程: ``` ┌─────────┐ ┌──────────┐ ┌─────────────┐ │ 用户浏览器│ │ OpenResty│ │OAuth提供商 │ └────┬────┘ └─────┬────┘ └──────┬──────┘ │ │ │ │ 1. 访问受保护资源 │ │ │───────────────────>│ │ │ │ │ │ 2. 检查 Cookie 中 │ │ │ 是否有 Token │ │ │ │ │ │ 3. 返回登录页面 │ │ │<───────────────────│ │ │ │ │ │ 4. 点击登录按钮 │ │ │───────────────────>│ │ │ │ │ │ 5. 重定向到 OAuth │ │ │<───────────────────│ │ │ │ │ │ 6. 用户扫码授权 │ │ │────────────────────────────────────────>│ │ │ │ │ 7. 回调并携带 code │ │ │<────────────────────────────────────────│ │ │ │ │ 8. 发送 code │ │ │───────────────────>│ │ │ │ │ │ │ 9. 用 code 换 token │ │ │─────────────────────>│ │ │ │ │ │ 10. 返回用户信息 │ │ │<─────────────────────│ │ │ │ │ │ 11. 生成 JWT Token │ │ │ │ │ 12. 设置 Cookie 并 │ │ │ 重定向到首页 │ │ │<───────────────────│ │ │ │ │ │ 13. 访问受保护资源 │ │ │ (携带 Token) │ │ │───────────────────>│ │ │ │ │ │ 14. 验证 Token 通过 │ │ │ │ │ │ 15. 返回资源内容 │ │ │<───────────────────│ │ ``` ## 📦 支持的 OAuth 提供商 | 提供商 | 状态 | 配置文件 | 图标 | |--------|------|----------|------| | 企业微信 (WeCom) | ✅ 已实现 | `oauth/wecom.lua` | `icons/wecom.svg` | | 飞书 (Feishu) | ✅ 已实现 | `oauth/feishu.lua` | `icons/feishu.svg` | | 钉钉 (DingDing) | ✅ 已实现 | `oauth/dingding.lua` | `icons/dingding.svg` | ## 📋 依赖要求 - **OpenResty** >= 1.21.4.1 (已测试 1.27.1.1) - **LuaJIT** 2.1 (OpenResty 内置) - **lua-resty-http** (用于 HTTP 请求) - **lua-resty-string** (用于字符串处理) ## 🚀 快速开始 ### 1. 安装 OpenResty **macOS (Homebrew):** ```bash brew install openresty ``` **Ubuntu/Debian:** ```bash sudo apt-get install openresty ``` **CentOS/RHEL:** ```bash sudo yum install openresty ``` ### 2. 安装依赖库 ```bash # 安装 lua-resty-http sudo opm install ledgetech/lua-resty-http # 安装 lua-resty-string sudo opm install openresty/lua-resty-string ``` ### 3. 克隆项目 ```bash git clone https://github.com/X-Mars/lua-resty-oauth2.git cd lua-resty-oauth2 ``` ### 4. 配置 OAuth 应用 编辑 `conf/config.lua`,填入你的 OAuth 应用凭证: ```lua -- 企业微信配置示例 oauth_providers = { wecom = { enabled = true, app_id = "your_corp_id", -- 企业 ID secret = "your_app_secret", -- 应用 Secret agent_id = "your_agent_id", -- 应用 AgentID redirect_uri = "https://yourdomain.com/oauth/callback" }, -- ...其他提供商配置 } -- JWT 密钥配置(重要:请修改为随机字符串) jwt = { secret = "your-super-secret-key-change-me", cookie_name = "auth_token", lifetime = 7200 -- Token 有效期(秒) } -- Cookie 配置 cookie = { domain = ".yourdomain.com", -- Cookie 域名(支持子域名) path = "/", secure = true, -- 生产环境建议开启 HTTPS httponly = true, samesite = "Lax" } ``` ### 5. 配置 Nginx 在你的 `nginx.conf` 中添加以下配置: ```nginx http { # Lua 包路径配置 lua_package_path "/path/to/lua-resty-oauth2/lua/?.lua;/path/to/lua-resty-oauth2/?.lua;;"; # 共享字典 lua_shared_dict oauth_cache 10m; # 启用代码缓存 lua_code_cache on; # DNS 解析器 resolver 8.8.8.8 ipv6=off; server { listen 443 ssl; server_name yourdomain.com; # SSL 证书配置 ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/cert.key; # OAuth 回调地址 location = /oauth/callback { access_by_lua_block { local auth = require "auth" auth.handle_callback() } } # OAuth 登出 location = /oauth/logout { access_by_lua_block { local auth = require "auth" auth.logout() } } # 受保护的资源 location / { access_by_lua_block { local auth = require "auth" auth.authenticate() } proxy_pass http://your_backend; # 传递用户信息给后端 proxy_set_header X-User-Id $http_x_user_id; proxy_set_header X-Auth-Type $http_x_auth_type; } } } ``` ### 6. 启动/重新加载 OpenResty ```bash # 测试配置 sudo openresty -t # 重新加载配置 sudo openresty -s reload ``` ### 7. 访问测试 访问 `https://yourdomain.com/`,应该会看到登录页面。 ## 📁 项目结构 ``` lua-resty-oauth2/ ├── lua/ # Lua 源代码 │ ├── auth.lua # 主鉴权模块 │ ├── i18n/ # 国际化模块 │ │ └── locale.lua # 语言翻译与检测 │ ├── oauth/ # OAuth 提供商实现 │ │ ├── wecom.lua # 企业微信 │ │ ├── feishu.lua # 飞书 │ │ └── dingding.lua # 钉钉 │ └── utils/ # 工具模块 │ └── jwt.lua # JWT 处理 ├── conf/ # 配置文件 │ └── config.lua # 主配置文件 ├── icons/ # OAuth 提供商图标 │ ├── wecom.svg │ ├── feishu.svg │ └── dingding.svg ├── docs/ # 文档目录 ├── README.md # 项目说明 ├── README_EN.md # 英文说明 ├── I18N.md # 国际化文档 ├── QUICKSTART.md # 快速开始 ├── DEPLOY.md # 部署指南 ├── EXAMPLES.md # 配置示例 ├── INTEGRATION_GUIDE.md # 集成指南 ├── PROJECT_OVERVIEW.md # 项目概览 └── LICENSE # 开源协议 ``` ## 🌍 多语言支持 本项目支持多语言界面,包括: - **English (en)**: 英语 - **简体中文 (zh-CN)**: 中国大陆 - **繁體中文 (zh-TW)**: 台湾、香港 ### 自动语言检测 系统会自动检测用户浏览器的语言设置(`Accept-Language` 头),并显示相应的界面语言。 ### 手动切换语言 用户可以通过以下方式手动切换语言: 1. **使用界面按钮**:登录页面右上角有语言切换按钮 2. **使用 URL 参数**:在 URL 中添加 `?lang=zh-CN` 或 `?lang=en` 示例: ``` https://yourdomain.com/?lang=en # 切换到英文 https://yourdomain.com/?lang=zh-CN # 切换到简体中文 https://yourdomain.com/?lang=zh-TW # 切换到繁体中文 ``` ### 添加新语言 详细的国际化配置和添加新语言的方法,请参考 [国际化文档 (I18N.md)](I18N.md)。 ## 🔧 配置说明 ### OAuth 提供商配置 每个 OAuth 提供商需要以下配置: ```lua { enabled = true, -- 是否启用 app_id = "...", -- 应用 ID / 企业 ID secret = "...", -- 应用密钥 agent_id = "...", -- 应用 AgentID (企业微信专用) redirect_uri = "..." -- 回调地址 } ``` ### 白名单配置 不需要鉴权的路径: ```lua whitelist = { "/oauth/callback", -- OAuth 回调地址 "/oauth/logout", -- 登出地址 "/health", -- 健康检查 "/static/", -- 静态资源 } ``` ### JWT 配置 ```lua jwt = { secret = "your-secret", -- 签名密钥(必须修改) cookie_name = "auth_token", lifetime = 7200, -- Token 有效期(秒) algorithm = "HS256" -- 签名算法 } ``` ## 🐛 故障排查 ### 常见问题 **1. 模块加载失败:`module 'auth' not found`** 检查 `lua_package_path` 是否配置正确: ```nginx lua_package_path "/path/to/lua-resty-oauth2/lua/?.lua;;"; ``` **2. DNS 解析失败:`no resolver defined`** 添加 DNS 解析器配置: ```nginx resolver 8.8.8.8 ipv6=off; ``` **3. SSL 证书验证错误:`unable to get local issuer certificate`** 在 OAuth HTTP 请求中禁用 SSL 验证(仅开发环境): ```lua local res, err = httpc:request_uri(url, { ssl_verify = false }) ``` **4. Cookie 未生效** 检查 Cookie domain 配置是否匹配访问域名: ```lua cookie = { domain = ".yourdomain.com" -- 注意前面的点 } ``` ### 调试日志 查看 OpenResty 错误日志: ```bash tail -f /path/to/openresty/logs/error.log ``` ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ### 开发指南 1. Fork 本项目 2. 创建特性分支 (`git checkout -b feature/AmazingFeature`) 3. 提交更改 (`git commit -m 'Add some AmazingFeature'`) 4. 推送到分支 (`git push origin feature/AmazingFeature`) 5. 提交 Pull Request ### 添加新的 OAuth 提供商 1. 在 `lua/oauth/` 下创建新的 Lua 文件 2. 实现 `get_auth_url()` 和 `get_user_info()` 方法 3. 在 `icons/` 下添加 SVG 图标 4. 更新 `conf/config.lua` 配置模板 5. 更新文档 ## 📄 开源协议 本项目采用 [MIT License](LICENSE) 开源协议。 ## 🙏 致谢 - [OpenResty](https://openresty.org/) - 高性能 Web 平台 - [lua-resty-http](https://github.com/ledgetech/lua-resty-http) - HTTP 客户端库 - [lua-resty-string](https://github.com/openresty/lua-resty-string) - 字符串处理库 ## 👨‍💻 作者 **火星小刘 (X-Mars)** - GitHub: [@X-Mars](https://github.com/X-Mars) - 项目主页: [lua-resty-oauth2](https://github.com/X-Mars/lua-resty-oauth2) ## 📮 联系方式 如有问题或建议,欢迎: - 提交 [GitHub Issue](https://github.com/X-Mars/lua-resty-oauth2/issues) - 发送邮件至项目维护者 --- ⭐ 如果这个项目对你有帮助,请给个 Star 支持一下!