Как правильно создать промежуточное программное обеспечение для аутентификации внутри AWS Lambda - PullRequest
0 голосов
/ 28 октября 2018

Я использую AWS Cognito для аутентификации своих пользователей, и после аутентификации они могут вызывать мой API (API Gateway + Lambda).Я делаю все это, используя Serverless Framework.

После проверки подлинности, когда они вызывают конечную точку, требующую этой проверки подлинности, моя лямбда получит атрибуты пользователя через request.RequestContext.Authorizer["claims"].У меня была идея создать промежуточное программное обеспечение для аутентификации, чтобы ввести текущего пользователя в контекст.Но я уверен, что делаю что-то не так (или могу быть улучшен).

Как это работает:

my-lambda-handler.go:

package main

import (
    "context"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/company/api/middlewares"
)

func Handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    fmt.Println(ctx.user)

    return events.APIGatewayProxyResponse{}, nil
}

func main() {
    lambda.Start(
        middlewares.Authentication(Handler),
    )
}

middlewares / authentication.go

package middlewares

import (
    "context"

    "github.com/aws/aws-lambda-go/events"
    "github.com/company/api/models"
)

func Authentication(next func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)) func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    var user models.User

    return func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
        claims := request.RequestContext.Authorizer["claims"]

        // Find user by claims properties.
        if err := user.Current(claims); err != nil {
            return events.APIGatewayProxyResponse{}, err
        }

        ctx.user = user
        return next(ctx, request)
    }
}

models / user.go:

package models

import (
    "github.com/jinzhu/gorm"
    "github.com/mitchellh/mapstructure"
)

type User struct {
    gorm.Model
    // Override ID cause we are using cognito.
    Email string `gorm:"primary_key,not null"`
    Site  Site
}

func (u *User) Current(claims interface{}) error {
    if err := mapstructure.Decode(claims, u); err != nil {
        panic(err)
    }

    if err := Database.Find(u).Error; err != nil {
        return err
    }
    return nil
}

У меня два вопроса:

  • Это правильный путьопределить функцию (функцию аутентификации), которая получает функцию и возвращает другую функцию?Поскольку это слишком многословно, я чувствую, что это неправильно.
  • Есть ли способ дополнить ctx атрибутом user?Способ, которым я пытаюсь, вижу ошибку ctx.user undefined (type context.Context has no field or method user)

Заранее спасибо.

...