【发布时间】:2019-04-03 00:06:48
【问题描述】:
我正在使用 AWS Cognito 对我的用户进行身份验证,一旦通过身份验证,他们就可以调用我的 API(API 网关 + Lambda)。我正在使用无服务器框架完成所有这些工作。
一旦通过身份验证,当他们调用需要此身份验证的端点时,我的 lambda 将通过request.RequestContext.Authorizer["claims"] 接收用户属性。我有创建一个身份验证中间件以将当前用户注入上下文的想法。但我确定我做错了什么(或者可以改进)。
它是如何工作的:
my-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),
)
}
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)
}
}
模型/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
}
我有两个问题:
- 这是定义接收一个函数并返回另一个函数的函数(身份验证函数)的正确方法吗?因为它太冗长了,我觉得这是错误的。
- 有没有办法用
user属性扩充ctx?我正在尝试的方式,我看到错误ctx.user undefined (type context.Context has no field or method user)。
【问题讨论】:
标签: amazon-web-services go aws-lambda amazon-cognito