iris 的 mvc 架构不内置 oauth 登录流程,需将 github 登录拆解为两个 controller 入口:/oauth/github/login 跳转授权页,/oauth/github/callback 处理回调、校验 state、换 token、拉取用户信息并绑定本地账号。

直接说结论: Iris 的 MVC 架构本身不内置 OAuth 登录流程,但可以干净地把 OAuth2 授权码流拆解为 Controller 方法 + 服务层封装,配合 Party 路由分组和中间件控制访问权限。关键不是“用哪个模板”,而是把授权跳转、code 换 access_token、用户信息拉取、本地账号绑定这四步落到 Controller 的 Action 上。
怎么写一个支持 GitHub 登录的 Controller
别试图在 BeforeActivation 或依赖注入里做重定向——Iris 的 MVC Controller 是纯响应逻辑,所有 OAuth 流程必须显式暴露为 HTTP handler。典型结构是两个入口:/oauth/github/login(跳转授权页)和 /oauth/github/callback(接收 code)。
常见错误现象:回调地址没配对、state 参数没校验、code 用完没丢弃导致重复使用失败。
-
/oauth/github/login方法生成带state和redirect_uri的 GitHub 授权 URL,并 302 跳转过去 -
/oauth/github/callback方法先验证state,再用code向https://github.com/login/oauth/access_tokenPOST 换access_token,最后调用https://api.github.com/user拿用户名、头像、id - 拿到 GitHub
id后,查本地users表:存在则签发 JWT;不存在则创建并绑定(注意邮箱可能为空)
为什么不能把 OAuth 逻辑塞进 Service 层自动调用
因为 OAuth2 授权码模式本质是跨域重定向协议,涉及浏览器跳转、CSRF 防护、临时 code 生命周期管理——这些无法被 Service 层“自动触发”。Iris 的 Service 注入只解决依赖复用,不解决 HTTP 协议流转。
容易踩的坑:app.Party("/oauth").Use(auth.Middleware) 这类中间件对登录流程无效,OAuth 的 /callback 必须是公开路由,认证发生在拿到 access_token 之后,而非请求进来时。
- 所有
/oauth/*路由都应绕过身份认证中间件 -
state必须存到 session(Iris 内置session.Start())或短期 Redis,不能只放内存变量 - GitHub 返回的
access_token是短期有效的,不要缓存它来代替本地用户 session
如何复用同一套 Controller 支持微信、Google 多平台
靠策略接口 + 工厂函数,而不是硬编码平台名。定义统一的 OAuthProvider 接口,包含 AuthURL()、TokenURL()、UserInfoURL()、ParseUser() 四个方法,每个平台实现一个 struct。
性能影响:不同平台字段差异大(微信返回 unionid,GitHub 返回 id,Google 返回 sub),ParseUser() 必须提取出可映射到本地用户的唯一键(推荐用平台 + 原始 ID 拼接成 github:123456)。
- 注册路由时用
app.Get("/oauth/{provider:string}/login", loginHandler),通过ctx.Params().Get("provider")动态选 provider - 避免在 Controller 里写 if-else 判断平台,把分支逻辑下推到
OAuthProvider实现中 - 微信要求回调域名备案且与业务域名一致,调试时得用真实二级域名,localhost 直接 401
最易被忽略的是 code 的一次性校验——Iris 没有自动帮你标记已使用,必须在换 access_token 成功后立刻在存储里标记该 code 为已消费,否则重放攻击可反复登录。











