如何在 AWS Lambda 中创建身份验证中间件

我正在使用 AWS Cognito 对我的用户进行身份验证,一旦通过身份验证,他们就可以调用我的 API (API Gateway + Lambda)。我正在使用无服务器框架完成所有这些工作。


一旦通过身份验证,当他们调用需要此身份验证的端点时,我的 lambda 将通过request.RequestContext.Authorizer["claims"]. 我有创建一个身份验证中间件以将当前用户注入上下文的想法。但我确定我做错了什么(或者可以改进)。


怎么运行的:


我的 lambda.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),

    )

}

中间件/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)

    }

}

型号/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

}



我有两个问题:

  • 这是定义接收函数并返回另一个函数的函数(身份验证函数)的正确方法吗?因为它太冗长了,我觉得这是错误的。

  • 有没有办法增加ctx一个user属性?我正在尝试的方式,我看到了错误ctx.user undefined (type context.Context has no field or method user)


慕的地6264312
浏览 95回答 1
1回答

慕雪6442864

关于使用中间件的第一个问题:这种方法当然没有错。如果您定义函数类型并使用定义的名称,函数看起来可能会好一些。net/http做同样的事情HandlerFunc:type HandlerFunc func(ResponseWriter, *Request)这将使中间件的签名更加合理:func AuthMiddleware(nextHop HandlerFunc) HandlerFunc编辑:lambda 库没有为函数签名定义这样的类型吗?我希望有一个存在。另外我不知道后缀Middleware在你的情况下是否有意义,但我认为一些后缀应该对你有意义,以便为函数名称提供更多上下文并使其更易于理解。AuthenticationMiddleware可能是一个例子。编辑:刚刚看到包名。LGTM 真的。第二个问题:还有一个常见的陷阱:context.WithValue返回要使用的新上下文。因此,您不应期望传递的参数上下文发生变化,而应使用返回的新参数上下文。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go