Artalk强行兼容非标准OAuth接口
众所周知,Artalk支持标准的OAuth接口的社交登录方式。但是有些奇怪的SSO提供的接口可能不是标准的OAuth,甚至Artalk和提供SSO的软件都不支持修改自己读取的路径或写入的路径。(点名Casdoor)
灵感来源:https://blog.liushen.fun/posts/8624756e/
登录的一般过程
本文将以Casdoor作为例子,实际根据相关接口情况思路通用。
在此之前我们需要了解Artalk的OAuth是如何验证的:
第一步首先你点击了“登录”按钮,然后选择了OAuth登录方式。这时候Artalk会跳转配置文件的Domain字段/authorize(此时查询参数携带client_id、redirect_uri、response_type、scope、state字段)这个目标登录页面,交由目标OAuth服务(Casdoor)来给用户提供服务。然后你在这个登录页面选择了 使用Github登录 ,跳转了Github官方的验证页。验证完成后会跳转到Github后台配置的回调Casdoor后端域名/callback交给Casdoor来验证和处理GitHub验证完成后的他们返回来的字段,Casdoor验证并处理完成后携带最终字段(Casdoor自己的授权码)重定向回由Artalk透传给Casdoor的redirect_uri(Artalk后端域名/api/v2/auth/auth0/callback)把授权码等材料递给Artalk,最终由Artalk调用 授权码换取Token(Casdoor后端域名/oauth/token) 和 获取用户身份信息(Casdoor后端域名/userinfo)接口后发布评论。(好长的流程)
简单来说就是这个流程:Artalk -> Casdoor -> Github -> Casdoor -> Artalk
对 Artalk 来说:它只认识 Casdoor,它以为 Casdoor 就是最终的账号系统。
对 GitHub 来说:它只认识 Casdoor,它不知道 Artalk 的存在。
Casdoor:起到了“中间人”和“翻译官”的作用,把五花八门的登录方式(GitHub, 微信, QQ等)统一成标准接口提供给 Artalk。
调用接口约定
遗憾的是,Casdoor的很多接口都不是标准OAuth接口,而Artalk是严格按照标准OAuth的查询路径进行调用的。
以下是 标准OAuth 调用约定:
1 | AUTH0_AUTHORIZE_URL = https://your-auth0-domain/authorize # 用户跳转登录页面,获取授权码 |
对应路径:/authorize:用户跳转到的目标登录页面(GET->html)/oauth/token:提供商验证已完成后授权码换Token(POST->json)/userinfo:登录后的用户基本信息接口(GET->json)
而 Casdoor 呢?它的接口是这样的:
1 | CASDOOR_AUTHORIZE_URL = https://your-casdoor-domain/login/oauth/authorize # 用户跳转 Casdoor 登录页面 |
对应路径:/login/oauth/authorize:用户跳转到的Casdoor登录页面(GET->html)/api/login/oauth/access_token:提供商验证已完成后授权码换Token(POST->json)/api/userinfo:登录后的用户基本信息接口(GET->json)
官方文档:https://www.casdoor.org/zh/docs/how-to-connect/oauth
对于Artalk默认行为,如果在回调被访问的时候连不到正确的Casdoor指定的授权码换Token这个接口的话,将会直接返回以下内容而无法继续:
1 | {"msg":"Field to complete user auth"} |
相关日志内容(这个日志在artalk.log或者docker运行日志都能看到):
1 | 2026/01/28 16:37:31.095 [31mERROR[0m [handler/auth_social_login.go:74] [SocialLogin] oauth2: cannot parse json: invalid character '<' looking for beginning of value |
这里的异常情况是Artalk按照标准OAuth接口去请求Casdoor后端,结果人家根本不是这个接口返回了404页面。最终Artalk拿不到期望的含有Token的json字符串导致异常。
如果是登录页面没做重定向的话因为Casdoor也没有那个路径,所有用户将直接被跳转到404页面而非期望的登录页面。
解决方法
我们需要做的是把OAuth标准接口映射到Casdoor等非标准Oauth接口上。/authorize 302重定向-> /login/oauth/authorize(因为是跳转到登录页,保留查询参数直接跳到Casdoor的统一入口)/oauth/token URL重写-> /api/login/oauth/access_token(因为这里是POST请求,只能路由映射)/userinfo 302重定向-> /api/userinfo(这里我用302重定向没出问题,如果有问题的话试着也换成URL重写)
这个顺序千万不能反!
具体操作:
如果你是二进制安装包安装的Casdoor,你可以用Nginx来实现。
如果是Docker安装并且直接打到公网的话,套一个CDN并直接在CDN测配置回源重写或302重定向到一个新目标。
对于腾讯的EdgeOne:
域名 -> 站点加速 -> 规则引擎
Nginx的方法就由大佬们来科研下吧,我安装方式原因没办法演示了。毕竟是生产环境嘛。
总结
其实这基本上就能解决几乎所有非标接口的对标问题了。当然它没法解决的是如果连查询参数的名字都不一样的情况,好在至少对于Artalk和Casdoor这两个系统来说没有抽象到这种地步。但是我觉得只要是OAuth的话参数基本都固定的(希望别真有那样的)
只需要知道使用的SSO系统它提供的接口对应着哪个标准接口就好说,直接像这样“赛博飞线”来解决这个问题。(不过我还是希望能给用户多点选择,不要总是硬编码了)



