未ログイン時の仕上げ
読了目安 約3分
投稿フォームの出し分けと、未ログインの POST の誘導を実装して、ねじ板を完成させます。
- ログイン済み 投稿できる
- セッション確認 状態で分ける
- 未ログイン ログインへ
この章の目次
残っているのは、未ログイン時の振る舞いです。
足すものは次の 2 つです。
- 投稿フォームをログイン中だけ表示する
- 未ログインの POST /posts をログイン画面へ誘導する
画面をログイン状態で出し分ける
未ログインの人には投稿フォームの代わりに、ログインと登録への案内を出します。 handleIndex の末尾、ExecuteTemplate を呼んでいた部分を次に置き換えます。
userName := ""
userID, loggedIn := currentUserID(r)
if loggedIn {
if err := db.QueryRow("SELECT name FROM users WHERE id = ?", userID).Scan(&userName); err != nil {
serverError(w, err)
return
}
}
data := map[string]any{
"Posts": posts,
"LoggedIn": loggedIn,
"UserName": userName,
}
if err := templates.ExecuteTemplate(w, "index.html", data); err != nil {
log.Println(err)
}templates/index.html も出し分けに対応させます。
{{if}} と {{else}} は、渡した値で出力を切り替えるテンプレートの条件分岐です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ねじ板</title>
</head>
<body>
<h1>ねじ板</h1>
{{if .LoggedIn}}
<p>{{.UserName}} さんとしてログイン中</p>
<form action="/logout" method="post">
<button type="submit">ログアウト</button>
</form>
<form action="/posts" method="post">
<textarea name="body" rows="3" cols="40"></textarea>
<button type="submit">投稿する</button>
</form>
{{else}}
<p>投稿するには<a href="/login">ログイン</a>が必要です。はじめての人は<a href="/register">ユーザー登録</a>へ。</p>
{{end}}
<ul>
{{range .Posts}}
<li>{{.UserName}}: {{.Body}}({{.CreatedAt.Format "2006-01-02 15:04"}})</li>
{{end}}
</ul>
</body>
</html>ログアウトがリンクではなく button 付きの form なのは、リンクは GET しか送れないからです(「状態を変える操作は POST」という 1 章の設計)。
未ログインの投稿はログイン画面へ
handleCreatePost の先頭で返していた 401 を、リダイレクトに変えます。
userID, ok := currentUserID(r)
if !ok {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}- POST /posts というリクエスト自体は、画面にフォームが無くても誰でも送れる(前章の curl がそうだった)。画面で隠すのは案内にすぎず、拒む仕事はサーバーにしかできない
- ここも「続きはこの URL を GET で見よ」という PRG パターンなので、2 章と同じ 303 See Other を使う。302 Found はブラウザによって GET への変更が保証されないため避ける
動作確認
シークレットウィンドウなど未ログインのブラウザで http://localhost:8080 を開いてください。 投稿フォームは無く、ログインへの案内が出ます。 そのままログインすると、フォームとログアウトボタンが現れます。
未ログインの POST も確かめます。
curl -i -d 'body=未ログインの投稿' http://localhost:8080/postsHTTP/1.1 303 See Other
Location: /loginこれでねじ板は完成です。 完成した main.go の全体と、機能を通しで確かめる手順は次章にまとめました。