将 OIDC 添加到我的 SPA 后反向代理错误网关
Posted
技术标签:
【中文标题】将 OIDC 添加到我的 SPA 后反向代理错误网关【英文标题】:Reverse Proxy Bad Gateway after adding OIDC to my SPA 【发布时间】:2022-01-14 11:50:59 【问题描述】:我正在将 keycloak 添加到我公司现有的用 Angular 编写的 SPA 中。
由于初始身份验证运行良好,我已经设法从 keycloak 获取 acess_token,但是当我尝试与我的 API 通信时,大约一半的请求会引发 502 bad gateway 错误。
当我在本地测试一切运行良好且完美无缺时,我现在正在我们的开发 kubernetes 集群上对其进行测试。
方案是这样的:
Web 应用程序(由 nginx 服务器提供的 angular SPA),nginx 服务器充当反向代理来与我的 api 对话
Api 服务器(用 nestJS 编写,带有对我的访问令牌的服务器端验证)
NGINX 服务器使用 clusterIP kubernetes 服务与 Api 服务器通信。
我相信问题来自 api 上的令牌验证,由于某种原因有时无法正常工作或需要太长时间,从而引发错误。
这就是它的样子:
@Injectable()
export class ownKeycloakStrategy extends PassportStrategy(BearerStrategy, 'keycloak')
constructor(private readonly openidService: OpenidService, private readonly staffService:StaffService,
private readonly adminService:AdminService)
super(
(token, done) => this.validate(token, done)
);
async validate(token, done): Promise<any>
var userInKC = null
try
userInKC = await this.openidService.validateToken(token);
catch (e)
return done(e)
// get Info from KC, if you cant means either user doesnt exist or token is not valid
//console.log(userInKC)
if(!userInKC) return done(new UnauthorizedException('Token not valid'))
// complete user object with info from our db
const userX: any = await Promise.all([
// here searches for user in own db
]).then(x => x.find(e => e !== null));
if (!userX) return done(new NotFoundException('User not found'))
// here we set up the user of the rerquest so our service can work properly
const user =
...userInKC,
_id: userX,
status: userX.status
return done(null, user, scope: 'all');
我的 validateToken 函数:
public async validateToken(token)
try
const public_key = await this.public_key()
if(public_key)
const decrypt = await this.keycloak.jwt.verifyOffline(token, public_key);
return decrypt.content
catch(e)
return this.keycloak.jwt.verify(token);
我尝试了什么:
更改我的 nginx conf 的代理缓冲以允许更大的 access_token 标头 尝试直接调用我的 api(我也收到错误的网关错误,这次我相信来自 traefik(我的集群负载均衡器)感谢您提供的任何帮助,如果您需要知道什么,请告诉我
谢谢
【问题讨论】:
【参考方案1】:这感觉就像您应该首先确保这不是 API 错误处理问题。首先测试失败场景,使用 curl 工具,然后在本地运行 API:
在没有授权标头的情况下调用 API 使用“xxx”等无效令牌调用 APIcurl -i http://localhost:3000/somepath \
-H "Authorization: Bearer xxx'
然后,您应该得到一个受控响应,例如错误对象,以及 401 的 HTTP 状态。响应可能需要一个 Access-Control-Allow-Origin 标头,以便 SPA 能够读取响应并采取正确的行动。
可靠的 JWT 验证
以下是 API 最常见的两种 JWT 故障场景:
客户端发送无效或过期的令牌 - 这将发生,因此 API 必须处理这种情况并返回 401 API 下载令牌签名公钥失败 - 在这种情况下,API 必须返回 500,因为 SPA 无法解决此问题并需要显示错误比较的东西
如果有帮助,请查看 this Node.js code example of mine 并注意它旨在返回适用于客户端的错误响应以及 API 中的日志记录详细信息。
NGINX
值得了解这是在做什么。最常见的设置是仅使用 proxy-path directive 传递整个请求和响应,包括所有标头。
INFRA
也许存在更深层次的基础设施问题,例如负载平衡器或 NGINX 路由到不健康的 API 服务器。不过,您应该能够遵循这种科学方法:
没有 API 日志,因此请求未到达 API 没有 NGINX 日志,因此请求没有到达反向代理 因此这是基础设施人员必须解决的问题【讨论】:
以上是关于将 OIDC 添加到我的 SPA 后反向代理错误网关的主要内容,如果未能解决你的问题,请参考以下文章
ID4 ADFS 3.0 和 oidc-client (vue spa) - 回调实现