post Image
Go×GAE×Dockerで作るGoogleOAuth認証アプリ

Dockerでローカル環境を楽に整えつつ、GAEをベースにしたアプリ開発ができれば最高だなあ。と常々思っていたので、今回はそれについて書きつつ、実践的なGoogleOAuth認証のアプリを作っていきたいと思います。

すぐにでもコードを見たい方はこちらをどうぞ。

https://github.com/gotokatsuya/gae-google

GAEとdepのDocker環境を整える

まずは DockerCompose をインストールしましょう。

公式サイトを参考にインストールしてください。

インストールできたら次はDockerイメージとComposeファイルを用意します。

今回はGAEベースのアプリケーションを作りたいので、mercariさんが提供してくれているGEAのDockerイメージを利用します。

加えて、ベンダリングのツールには「dep」を利用するので、いい感じのDockerイメージを探してきてComposeファイルに追加します。

docker-compose.yaml
version: '2'
services:
  app:
    image: mercari/appengine-go:1.8
    working_dir: /go/src/github.com/gotokatsuya/gae-google
    command: make serve-dev
    ports:
      - 8080:8080
      - 8000:8000
    volumes:
      - .:/go/src/github.com/gotokatsuya/gae-google
  dep:
    image: instrumentisto/dep:0.3.2
    working_dir: /go/src/github.com/gotokatsuya/gae-google
    volumes:
      - .:/go/src/github.com/gotokatsuya/gae-google

このようなdocker-compose.ymlを用意するだけでローカル開発が最高に楽になります。

GoogleOAuth認証アプリを作る

GoogleOAuth認証設定

コードを書く前にGoogleOAuthの設定をして、ClientIDとClientSecretを取得、そしてRedirectURLをセットします。設定方法は公式サイトが参考になります。

今回のアプリケーションではRedirectURLはhttp://localhost:8080/auth/google/callbackを指定してください。ClientIDとClientSecretはapp.yamlに環境変数として記載します。

app.yml
application: gae-google
version: 1
runtime: go
api_version: go1.8
handlers:
- url: /.*
  script: _go_app
  secure: always
env_variables:
  AUTH_GOOGLE_CLIENT_ID: "xxx"
  AUTH_GOOGLE_CLIENT_SECRET: "xxx"
  AUTH_GOOGLE_REDIRECT_URL: "http://localhost:8080/auth/google/callback"

実際にコードを書いていく

まずはRoutingから作ります。

routes.go
package routes

import (
    "net/http"

    "github.com/gorilla/mux"
    "github.com/urfave/negroni"

    "github.com/gotokatsuya/gae-google/app/controllers"
)

var (
    App = negroni.New(negroni.NewRecovery())
)

func init() {
    router := mux.NewRouter()

    authRouter := router.PathPrefix("/auth").Subrouter()
    authRouter.Path("/login").HandlerFunc(controllers.AuthLoginHandler).Methods(http.MethodGet)
    authRouter.Path("/google").HandlerFunc(controllers.AuthGoogleHandler).Methods(http.MethodGet)
    authRouter.Path("/google/callback").HandlerFunc(controllers.AuthGoogleCallbackHandler).Methods(http.MethodGet)

    App.UseHandler(router)
}

Contollerを作っていきます。

controller.go
package controllers

import (
    "net/http"

    "google.golang.org/appengine"

    "github.com/gotokatsuya/gae-google/lib/template"

    "github.com/gotokatsuya/gae-google/app/services/auth"
)

// AuthLoginHandler HTMLをレンダリングする
func AuthLoginHandler(w http.ResponseWriter, r *http.Request) {
    template.Render.HTML(w, http.StatusOK, "auth/login", nil)
}

// AuthGoogleHandler Googleログイン
func AuthGoogleHandler(w http.ResponseWriter, r *http.Request) {
    svc := auth.NewService()
    // ランダム値を生成する
    state := svc.GenerateState()
    // CallbackするURLを生成する
    url := svc.GoogleAuthURL(state)
    // 生成したランダム値ををセッションに保存する
    svc.SaveState(state, r, w)
    http.Redirect(w, r, url, http.StatusFound)
}

// AuthGoogleCallbackHandler Googleログイン認証結果
func AuthGoogleCallbackHandler(w http.ResponseWriter, r *http.Request) {
    ctx := appengine.NewContext(r)
    svc := auth.NewService()
    // セッションに保存されているランダム値と比較して一致するかどうか確認
    if r.URL.Query().Get("state") != svc.State(r) {
        http.Error(w, "invalid state", http.StatusUnauthorized)
        return
    }
    // GoogleログインしたユーザーのメールアドレスやIDを取得する
    if err := svc.GoogleLogin(ctx, r.URL.Query().Get("code")); err != nil {
        http.Error(w, err.Error(), http.StatusUnauthorized)
        return
    }

    // 適当な画面に飛ばす
    http.Redirect(w, r, "https://eure.jp", http.StatusFound)
}

DockerComposeを使って起動する

最初に記載したように今回はdepを使って依存ライブラリをベンダリングします。今回はvendorフォルダをgit管理しているので実行する必要はないですが、initを実行するとvendorフォルダが作られ、ライブラリをベンダリングしてくれるようになります。

// $ docker-compose run --rm dep init

GAEに載せるアプリケーションを起動します。

$ docker-compose up app

起動後に http://localhost:8080/auth/login へアクセスするとこのようなシンプルな画面がレンダリングされるはずです。

スクリーンショット 2017-12-09 0.17.14.png

「Google Login」ボタンを押下するとログイン画面が立ち上がります。ログインに成功すると、適当に設定したeurekaのHPに遷移します。

スクリーンショット 2017-12-09 0.35.47.png


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。