Iris框架实现OAuth2需明确客户端或资源服务器角色:作为客户端时用golang.org/x/oauth2对接微信等,关键约束包括RedirectURL严格一致、state防CSRF、Exchange传请求上下文;作为资源服务器则需手动校验第三方token并提取user_id。

Iris 框架本身不提供 OAuth2 Server 功能,所谓“API 接入 OAuth2”,实际是让 Iris 作为 OAuth2 客户端(对接微信、GitHub 等)或作为资源服务器(校验第三方颁发的 token),二者完全不是一回事——选错路径,代码写完也跑不通。
OAuth2.Client 模式:用 golang.org/x/oauth2 对接微信/GitHub/Google
这是最常见需求:用户点“微信登录”,跳转授权,回调后拿到 access_token,再调 /sns/userinfo 拿头像昵称。关键不在 Iris,而在 oauth2.Config 的四个硬约束:
-
RedirectURL必须和微信开放平台后台填的值逐字节一致(含协议、端口、路径、末尾斜杠),本地开发统一用http://localhost:8080/auth/callback,生产必须 HTTPS -
state参数要自己生成(crypto/rand.Read+ hex)、存 session、回调时恒定时间比对(cmp.Equal或subtle.ConstantTimeCompare),漏掉就等于开放 CSRF 入口 -
Exchange()必须传ctx.Request().Context(),不能用context.Background();错误类型要区分:*oauth2.RetrieveError说明 IDP 返回了 JSON 错误体(如{"error":"invalid_grant"}),得解析后返回给前端 - 微信的
redirect_uri在拼 AuthURL 时要手动 URL 编码(url.QueryEscape(config.RedirectURL)),GitHub/Google 不需要——别套用通用逻辑
OAuth2.Resource Server 模式:校验第三方 token 并放行 API
Iris 不内置 token 解析中间件,你得自己写 handler 去验证 bearer token。典型场景是:前端传 Authorization: Bearer ya29.a0...(来自 Google 登录),后端调 Google 的 https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=... 验证有效性并提取 user_id:
- 不要只 base64 解
access_token取exp字段——这绕过签名校验,token 被盗用也无法察觉 - 必须发起 HTTP 请求到 IDP 的
/tokeninfo或/introspect端点(取决于 provider),且要加超时(建议 ≤2s)和重试(1次) - 验证通过后,把
user_id写进ctx.Values().Set("user_id", userID),后续 handler 直接取用 - 注意 scope 校验:如果 API 要求
email权限,但 token 只有profile,就得拒绝
Session 共享不配 Redis,SSO 就是假的
如果你用 nginx 做负载均衡,跑多个 Iris 实例,默认内存 session 会让用户在 A 实例登录后,下次请求落到 B 实例时 session 丢失——他得重新点微信登录,这直接破坏单点登录体验:
- 必须换 session 存储后端:
github.com/kataras/iris/v12/sessions支持 Redis、PostgreSQL、BadgerDB 等 - Redis 配置示例:
sessions.New(sessions.Config{Cookie: "sessionid", Provider: sessions.NewRedisProvider("redis://127.0.0.1:6379")}) - 别忽略
ProviderConfig里的MaxAge和Secure:生产环境必须设Secure: true(HTTPS only),否则 cookie 可被中间人窃取
OIDC 是更安全的选择,但别跳过 go-oidc 的 verifier.Verify()
如果对接的是支持 OpenID Connect 的 IdP(如 Auth0、Okta、Azure AD),优先走 OIDC 而非纯 OAuth2——它多一层 ID Token 校验,能确认用户身份而非仅授权:
- 必须用
github.com/coreos/go-oidc的verifier.Verify(ctx, rawIDToken),不能自己jwt.Parse后只检查exp和iss -
oauth2.Config.RedirectURL和 IdP 后台注册的回调地址必须完全一致,差一个字符都报invalid_request - Id Token 的
nonce要在生成 AuthURL 时生成并存 session,回调时传给verifier.Verify(),否则防不了重放攻击
真正卡住人的从来不是代码量,而是 RedirectURL 多了一个空格、state 没做恒定时间比对、或者 session 没切 Redis——这些细节不会报明显错误,只会让流程在某个环节静默失败,查日志都找不到线索。


















