【Go】echoフレームワークでログイン機能を作成する
2017.03.14
こんにちは。ユニトラストの白石です。
今回はGoで作成されたフレームワークecho(v3.0.3)でログイン機能を実装する形で紹介します。
echoとは
Go製の軽量なフレームワークの1つです。「golang echo」で使用例を検索するとjsonを返すAPIサーバーの事例が多いですが、Goのパッケージであるhtml/templateを使うことでwebアプリケーションの開発も可能です。また、echoは拡張性が高く、Middleware群によって機能を追加することができます。
インストール
echoは「go get github.com/labstack/echo」のコマンドで簡単にインストールすることができます。
コード
下記のコードがログイン機能を実装した全コードです。抜粋しながら説明をしていきます。
package main
import (
"io"
"github.com/labstack/echo"
"html/template"
"net/http"
"html"
"github.com/ipfans/echo-session"
)
type Template struct {
templates *template.Template
}
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
func main() {
var e = echo.New()
//テンプレートの設定
t := &Template{
templates: template.Must(template.ParseGlob("static/template/*.html")),
}
e.Renderer = t
//セッションを設定
store := session.NewCookieStore([]byte("secret-key"))
//セッション保持時間
store.MaxAge(86400)
e.Use(session.Sessions("ESESSION", store))
e.GET("/login", ShowLoginHtml)
e.POST("/login", Login)
// ポート9000でサーバーを起動
e.Logger.Fatal(e.Start(":9000"))
// Let's Encrypt から証明書を自動取得してhttpsサーバーを起動
//e.Logger.Fatal(e.StartAutoTLS(":443"))
}
type LoginForm struct {
UserId string
Password string
ErrorMessage string
}
type CompleteJson struct {
Success bool `json:"success"`
}
func ShowLoginHtml(c echo.Context) error {
session := session.Default(c)
loginId := session.Get("loginCompleted")
if loginId != nil && loginId == "completed" {
completeJson := CompleteJson{
Success: true,
}
return c.JSON(http.StatusOK, completeJson)
}
return c.Render(http.StatusOK, "login", LoginForm{})
}
func Login(c echo.Context) error {
loginForm := LoginForm{
UserId: c.FormValue("userId"),
Password: c.FormValue("password"),
}
userId := html.EscapeString(loginForm.UserId)
password := html.EscapeString(loginForm.Password)
if userId != "userId" && password != "password" {
loginForm.ErrorMessage = "ユーザーID または パスワードが間違っています"
return c.Render(http.StatusOK, "login", loginForm)
}
//セッションにデータを保存する
session := session.Default(c)
session.Set("loginCompleted", "completed")
session.Save()
completeJson := CompleteJson{
Success: true,
}
return c.JSON(http.StatusOK, completeJson)
}
main
mainメソッドを見ていきます。
最初にechoを初期化します。
var e = echo.New()
今回はログイン画面にテンプレートを使うので、echoにテンプレートを設定します。(/static/templateディレクトリ以下のhtmlを対象にしています)
//テンプレートの設定
t := &Template{
templates: template.Must(template.ParseGlob("static/template/*.html")),
}
e.Renderer = t
未ログインとログイン中を区別するために、Middlewareのecho-sessionを使って、ログイン情報をセッションに保持します。(echo-sessionはgo get github.com/ipfans/echo-sessionでインストールします)
//セッションを設定
store := session.NewCookieStore([]byte("secret-key"))
//セッション保持時間
store.MaxAge(86400)
e.Use(session.Sessions("ESESSION", store))
/loginにGETでアクセスをするとShowLoginHtmlメソッドが呼ばれます。
e.GET("/login", ShowLoginHtml)
/loginにPOSTでアクセスするとLoginメソッドが呼ばれます。
e.POST("/login", Login)
最後にサーバーを起動します。起動に失敗したらログが出力されます。
// ポート9000でサーバーを起動
e.Logger.Fatal(e.Start(":9000"))
ShowLoginHtml
ShowLoginHtmlメソッドを見ていきます。
ログイン中だった場合はJSONを返します。
ログイン中でなかった場合はlogin.htmlのテンプレートを表示します。第3引数に空の構造体を使います。(構造体のstringはnilではなく空文字です)
return c.Render(http.StatusOK, "login", LoginForm{})
Login
Loginメソッドを見ていきます。
フォームからpostされた値を確認して、ユーザーIDとパスワードに一致していた場合は、JSONを返します。
一致していない場合は、ShowLoginHtmlでは空だったLoginForm構造体のメンバにユーザーが入力したパラメーターとエラーメッセージを設定して、login.htmlのテンプレートを表示します。こうすることで、前回の入力とエラーメッセージが表示されます。
(今回はユーザーIDとパスワードをコードに書いていますが、ユーザーIDとsaltを使ったhash化したパスワードをDBに保存するのが適切です。)
loginForm := LoginForm{
UserId: c.FormValue("userId"),
Password: c.FormValue("password"),
}
loginForm.ErrorMessage = "ユーザーID または パスワードが間違っています"
return c.Render(http.StatusOK, "login", loginForm)
テンプレート
LoginForm.ErrorMessageが空文字でない(ne)ときに、エラーメッセージを表示します。if文の条件にはne(不一致)の他に、eq(一致)、lt(より下)、le(以下)、gt(より上)、ge(以上)があります。
詳しくは、公式ドキュメントを参照してください。
{{define "login"}}
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<title>ログイン</title>
</head>
<body>
<form action="/login" method="post">
{{if ne .ErrorMessage ""}}
<p>{{.ErrorMessage}}</p>
{{end}}
<p>ユーザーID</p>
<p><input type="text" name="userId" value="{{.UserId}}"></p>
<p>パスワード</p>
<p><input type="password" name="password" value="{{.Password}}"></p>
<p><input type="submit" value="ログイン"></p>
</form>
</body>
</html>
{{end}}
まとめ
今回、echoを使ってログイン機能を作成しました。紹介したechoの機能は一部に過ぎません。例えば、Basic認証を設定したり、Let’s Encryptから自動で証明書を取得する機能などもあります。この機会にPHP、Javaから離れて、GoでWebアプリケーションを作成してみてはいかがでしょうか?
CONTACT
お問い合わせ
あなたの「想い」に挑戦します。
どうぞお気軽にお問い合わせください。
受付時間:平日9:00〜18:00 日・祝日・弊社指定休業日は除く






