AWS Cognitoを使用してユーザーを認証しています。認証されると、ユーザーはAPI(API Gateway + 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),
)
}
ミドルウェア/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
}
2つの質問があります。
ctx
とのuser
属性は?私が試みている方法で、エラーが表示されますctx.user undefined (type context.Context has no field or method user)
。ミドルウェアの使用に関する最初の質問:
確かにこのアプローチには何も問題はありません。関数のタイプを定義し、定義した名前を使用すると、関数の外観が少し良くなる可能性があります。net/http
同じことをHandlerFunc
:
type HandlerFunc func(ResponseWriter, *Request)
これにより、ミドルウェアの署名がより合理的になります。
func AuthMiddleware(nextHop HandlerFunc) HandlerFunc
編集:ラムダライブラリは関数シグネチャにそのようなタイプを定義していませんか?存在すると思います。
また、接尾辞Middleware
があなたの場合に意味があるかどうかはわかりませんが、関数の名前にもう少しコンテキストを与えて理解しやすくするために、いくつかの接尾辞は意味があるはずです。AuthenticationMiddleware
例かもしれません。
編集:パッケージ名を見ただけです。LGTMは本当に。
2番目の質問:
の正しい使い方については、こちらをご覧くださいcontext
。共通の落とし穴もありcontext.WithValue
ます。使用する新しいコンテキストを返します。したがって、渡されたパラメータコンテキストが変更されることを期待してはならず、返される新しいコンテキストを使用する必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加