ログイン機能を作ろうと思ったのでGAE/Goで実装してみた
GAE/Go 2nd-genとは
2nd-genの変更点は、ここでまとめられるので読むと分かるかも
実装
公式のサンプルがあるので、これを元に作成
app.yaml
■app.yaml
runtime: go111
「runtime: go111」で使えるようになります
取り敢えず、動くものをデプロイしてみる
■app.go
package main import ( "net/http" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) r.Run() }
ローカルで確認
$ dev_appserver.py app.yaml
確認
$ curl http://localhost:8080/ping {"message":"pong"}
動いているを確認したらデプロイ。。。 する前にvgoで依存管理をする
$ export GO111MODULE=on $ go mod init $ go mod vendor
これで、「vendor」フォルダにmoduleが入る
これでデプロイ
$ gcloud app deploy
これでAPIとして利用可能になった
firebase Authを実装
あとはfirebase Authの実装を追加
まずMiddlewareを書く
■ middleware/firebase.go
package middleware import ( "context" "net/http" "os" "strings" firebase "firebase.google.com/go" "github.com/gin-gonic/gin" "golang.org/x/oauth2/google" "google.golang.org/api/option" ) func FirebaseAuthMiddleWare(gc *gin.Context) { ctx := context.Background() creds, err := google.CredentialsFromJSON(ctx, []byte(os.Getenv("FIREBASE_SERVICE_ACCOUNT_JSON"))) if err != nil { gc.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": err.Error()}) return } opt := option.WithCredentials(creds) app, err := firebase.NewApp(context.Background(), nil, opt) if err != nil { gc.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": err.Error()}) return } auth, err := app.Auth(context.Background()) if err != nil { gc.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": err.Error()}) return } idToken := strings.Replace(gc.GetHeader("Authorization"), "Bearer ", "", 1) _, err = auth.VerifyIDToken(context.Background(), idToken) if err != nil { gc.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": err.Error()}) return } gc.Next() }
環境変数にfirebaseの設定を追加
■app.yaml
runtime: go111 env_variables: FIREBASE_SERVICE_ACCOUNT_JSON: | { "type": "**************", "project_id": "**************", "private_key_id": "**************", "private_key": "**************", "client_email": "**************", "client_id": "**************", "auth_uri": "**************", "token_uri": "**************", "auth_provider_x509_cert_url": "**************", "client_x509_cert_url": "**************" }
最後にcorsとmiddlewareの設定を追加して完了
■app.go
package main import ( "net/http" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "github.com/wheatandcat/Peperomia/backend/handler" "github.com/wheatandcat/Peperomia/backend/middleware" ) func main() { r := gin.Default() r.Use(cors.New(cors.Config{ AllowOrigins: []string{"https://foo.com"}, AllowMethods: []string{ http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodOptions, }, AllowHeaders: []string{ "Authorization", "Content-Type", "Cache-Control", }, AllowCredentials: true, MaxAge: 86400, })) r.Use(middleware.FirebaseAuthMiddleWare) h := handler.NewHandler() r.POST("/SaveUser", h.SaveUser) r.Run() }
これで取り敢えず、認証してAPIアクセスのができるはず、 次回はフロント側の実装の紹介をしようと思います。
今回の修正のpull request
Firebaseログインを追加する by wheatandcat · Pull Request #12 · wheatandcat/Peperomia · GitHub