تایپاسکریپت - احراز هویت سفارشی برای رویداد اتصال وبسوکت فراخوانی نمیشود


من در حال تلاش برای پیادهسازی یک مجوزدهنده سفارشی برای یک API Gateway Websocket API هستم.

من مجوزدهنده سفارشی خود را به این صورت با استفاده از 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',
});

وقتی تلاش میکنم به این API وبسوکت متصل شوم، یک callback بستن اتصال با کد 1006 دریافت میکنم. اما وقتی لاگهای CloudWatch را بررسی میکنم، گروه لاگی برای تأییدگر سفارشی من وجود ندارد، بنابراین به نظر میرسد که لامبدا طبق انتظار فراخوانی نمیشود.

من به این صورت وصل میکنم:

ws = new WebSocket(`wss://${host}/${stage}?token=${authToken}`);

قبل از اضافه کردن مجوزدهنده سفارشی، اتصال وبسوکت موفق بود و API همانطور که انتظار میرفت کار میکرد.

من قادر هستم تا لامبدای مجوزدهنده سفارشی را با استفاده از تابع Test در کنسول اجرا کنم و لاگها طبق انتظار ایجاد میشوند.

اینجا پیادهسازی هندلر مجوزدهنده است:

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,
            },
        ],
        },
    };
}

چه چیزی را از قلم انداختهام که این مجوزدهندهٔ سفارشی کار کند؟

پاسخ شماره ۱

من متوجه شدم. من باید آرگومان identitySource را به اعلامیه WebSocketLambdaAuthorizer اضافه میکردم:

const authorizer = new WebSocketLambdaAuthorizer(
    "WebsocketAuth",
    authFunc,
    {
        identitySource: ['route.request.querystring.token']
    }
);

این مورد ضروری است، زیرا ظاهراً مجوزدهنده فراخوانی نخواهد شد اگر فیلدها در identitySource وجود نداشته باشند، و identitySource پیشفرض، هدر Authorization است که بهراحتی برای اتصالات وبسوکت قابل تنظیم نیست.