WebSocket API自定义授权器未触发连接事件问题排查
问题
我正尝试为API Gateway WebSocket API实现自定义授权器,使用AWS CDK完成如下配置:
const authFunc = new lambda.Function(scope, utils.prefixed("WebsocketAuth"), { runtime: lambda.Runtime.NODEJS_18_X, handler: `auth.handler`, code: lambda.Code.fromAsset(lambdaPath), environment: { API_KEY_ID: apiKey.keyId } }); const authorizer = new WebSocketLambdaAuthorizer( "WebsocketAuth", authFunc ); const webSocketApi = new apigatewayv2.WebSocketApi(scope, 'WebSocketApi', { connectRouteOptions: { authorizer, integration: new integrations.WebSocketLambdaIntegration('ConnectHandler', connectFunc), }, disconnectRouteOptions: { integration: new integrations.WebSocketLambdaIntegration('DisconnectHandler', disconnectFunc) }, defaultRouteOptions: { integration: new integrations.WebSocketLambdaIntegration('DefaultHandler', defaultFunc), }, routeSelectionExpression: '$request.body.action', });
当尝试连接该WebSocket API时,收到代码为1006的连接关闭回调,但CloudWatch中无自定义授权器的日志组,说明该Lambda未被调用。连接代码为:
ws = new WebSocket(`wss://${host}/${stage}?token=${authToken}`);
添加自定义授权器前WebSocket连接正常,且在控制台测试该授权器Lambda可正常执行并生成日志。授权器处理函数实现如下:
import { APIGatewayRequestAuthorizerEvent, APIGatewayAuthorizerResult } from 'aws-lambda'; const secret = process.env.API_SECRET ?? ''; export const handler = async (event: APIGatewayRequestAuthorizerEvent): Promise<APIGatewayAuthorizerResult> => { console.log(`Event: ${JSON.stringify(event)}`); const query = event.queryStringParameters ?? { token: 'NONE' }; const token = query['token']; console.log(`Query: ${JSON.stringify(query)}`); if (token === secret) { console.log(`Allowed`); return generatePolicy('user', 'Allow', event.methodArn); } else { console.log(`Denied`); return generatePolicy('user', 'Deny', event.methodArn); } }; function generatePolicy(principalId: string, effect: string, resource: string) { return { principalId, policyDocument: { Version: '2012-10-17', Statement: [ { Action: 'execute-api:Invoke', Effect: effect, Resource: resource, }, ], }, }; }
请问我遗漏了什么配置才能让自定义授权器正常工作?
解决方案
你遗漏了以下关键配置,导致授权器未被触发:
- 未指定授权器的身份来源
WebSocket自定义授权器必须明确告知API Gateway从哪里提取身份凭证。你当前创建WebSocketLambdaAuthorizer时未配置identitySource,API Gateway无法定位到请求中的token参数,因此不会触发授权Lambda。
修改授权器定义,添加身份来源配置:
const authorizer = new WebSocketLambdaAuthorizer( "WebsocketAuth", authFunc, { identitySource: ['$request.querystring.token'] // 指定从查询参数提取token } );
- Lambda环境变量不匹配
授权器代码中使用的是API_SECRET环境变量,但CDK配置里给授权Lambda设置的是API_KEY_ID,这会导致授权逻辑中secret为空值,即使token正确也会被拒绝。修正环境变量配置:
const authFunc = new lambda.Function(scope, utils.prefixed("WebsocketAuth"), { runtime: lambda.Runtime.NODEJS_18_X, handler: `auth.handler`, code: lambda.Code.fromAsset(lambdaPath), environment: { API_SECRET: apiKey.secretArn // 替换为实际的密钥值,确保和前端传入的token匹配 } });
- 确认API Gateway阶段的权限绑定
虽然CDK通常会自动生成权限,但仍需确认:- 授权Lambda的权限策略中是否包含API Gateway的调用权限;
- WebSocket API的
$connect路由是否确实绑定了该授权器(可在AWS控制台的API Gateway -> WebSocket API -> 路由 -> $connect中查看)。
内容的提问来源于stack exchange,提问作者sak
相关产品推荐
相关产品推荐

