質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

5347閲覧

【Golang】HTMLからFormで送られてきた文字列をJSON形式に変換し構造体に格納する方法

suptree

総合スコア5

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/09/22 09:57

前提・実現したいこと

Golangを使用して、ログイン機能を実装しようとしています。
こちらの記事を参考にしています。
https://qiita.com/__init__/items/21b2604db54867f8c543

この記事では、Rclient というものを使用しサーバー側にログイン情報を渡しています。
しかし、プラウザを使用してログイン情報を渡そうと試しているのですがエラーが出ます。
フォームデータをjson形式に変換して、User構造体に格納する方法を教えていただきたいです。

発生している問題・エラーメッセージ

プラウザでemail情報とpassword情報を打つと {"message":"Email は必須です。"} と表示されます。

該当のソースコード

go

1package main 2 3import ( 4 "database/sql" 5 "encoding/json" 6 "first-webserver/config" 7 "first-webserver/tool" 8 "fmt" 9 "html/template" 10 "log" 11 "net/http" 12 13 "github.com/gorilla/mux" 14 "github.com/lib/pq" 15 "golang.org/x/crypto/bcrypt" 16) 17 18var db *sql.DB 19 20func main() { 21 //param.go から DB の URL を取得 22 i := tool.Info{} 23 24 pgUrl, err := pq.ParseURL(i.GetDBUrl()) 25 if err != nil { 26 log.Fatal(err) 27 } 28 //DB接続 29 db, err = sql.Open("postgres", pgUrl) 30 if err != nil { 31 log.Fatal(err) 32 } 33 34 //マルチプレクサを定義 35 router := mux.NewRouter() 36 37 router.HandleFunc("/signup", Signup).Methods("POST") 38 router.HandleFunc("/login", Login) 39 //.Methods("POST") 40 41 //terminalに出力 42 log.Println("サーバー起動 : 8000 port で受信") 43 44 log.Fatal(http.ListenAndServe(":8000", router)) 45}

go

1func Login(w http.ResponseWriter, r *http.Request) { 2 // w.Write([]byte("successfully called login")) 3 fmt.Println("method:", r.Method) //リクエストを取得するメソッド 4 5 var user config.User 6 var error config.Error 7 var jwt config.JWT 8 9 if r.Method == "GET" { 10 t, _ := template.ParseFiles("front/login.gtpl") 11 t.Execute(w, nil) 12 } else { //POST 13 r.ParseForm() 14 15 16 json.NewDecoder(r.Body).Decode(&user) 17 18 if user.Email == "" { 19 error.Message = "Email は必須です。" 20 config.ErrorInResponse(w, http.StatusBadRequest, error) 21 return 22 } 23 24 if user.Password == "" { 25 error.Message = "Password は必須です。" 26 config.ErrorInResponse(w, http.StatusBadRequest, error) 27 return 28 } 29 30 password := user.Password 31 fmt.Println("password: ", password) 32 33 //認証キー(Email)// NOTEのユーザー情報をDBから取得 34 row := db.QueryRow("SELECT * FROM USERS WHERE email=$1;", user.Email) 35 err := row.Scan(&user.ID, &user.Email, &user.Password) 36 37 if err != nil { 38 if err == sql.ErrNoRows { 39 error.Message = "ユーザーが存在しません。" 40 config.ErrorInResponse(w, http.StatusBadRequest, error) 41 } else { 42 log.Fatal(err) 43 } 44 } 45 46 hasedPassword := user.Password 47 fmt.Println("hasedPassword: ", hasedPassword) 48 49 err = bcrypt.CompareHashAndPassword([]byte(hasedPassword), []byte(password)) 50 if err != nil { 51 error.Message = "無効なパスワードです" 52 config.ErrorInResponse(w, http.StatusUnauthorized, error) 53 return 54 } 55 56 token, err := tool.CreateToken(user) 57 58 if err != nil { 59 log.Fatal(err) 60 } 61 62 w.WriteHeader(http.StatusOK) 63 jwt.Token = token 64 65 config.ResponseByJSON(w, jwt) 66 fmt.Println(token) 67 } 68} 69

Go

1type User struct { 2 ID int `json:"id"` 3 Email string `json:"email"` 4 Password string `json:"password"` 5} 6

html

1<html> 2<head> 3<title></title> 4</head> 5<body> 6<form action="/login" method="post"> 7 EmailAddresses:<input type="text" name="email"> 8 password:<input type="password" name="password"> 9 <input type="submit" value="submit"> 10</form> 11</body> 12</html> 13

試したこと

Login関数の r.ParseForm() の下の json.NewDecoder(r.Body).Decode(&user)json.NewDecoder(r.Form).Decode(&user) に変更しても型がmissmatchというエラーが出ました。

また、
login関数の部分を

Go

1form, _ := json.Marshal(r.Form) 2json.NewDecoder(form).Decode(&user)

のようにフォームデータをjson形式に変換してみましたがだめでした。

補足情報(FW/ツールのバージョンなど)

ubuntu18.04 LTS
Go version : 1.10.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

アプローチは2種類。

  • 受け取ったFormを普通にパースした後、ひとつひとつ構造体に詰め替える。
  • フロント側から送信するフォームをapplication/jsonで送る。

基本どちらも手間がかかるのは同じです。
ライブラリパワーで省力化する方法があるだけです。

後者のアイディアは 過去の質問 に回答しました。

投稿2019/09/22 22:55

編集2019/09/22 23:11
nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobonobo

2019/09/24 01:33

要するに現状フロント(JS)側でどうにか(JSONにエンコード)しない限り、Formのデータは「application/x-www-form-urulencoded」か「multipart/form-data」になるのでサーバー側にてJSONでデコードはできません。
nobonobo

2019/09/24 01:39

Rclient?は詳細は知りませんが、JSONのPOSTボディを構築するフロントエンドを持っているようです。 例示のHTMLにはありません(submitするとapplication/x-www-form-urulencodedなBodyを送信します)。HTML側を変更しないのであればJSONでデコードはできません。
nobonobo

2019/09/24 01:45

また、先のサンプルのjson.NewDecoder(r.Body).Decode(&user) ここでエラーをチェックしていないのは後々泣くことになるので必ずチェックしましょう。
suptree

2019/10/01 14:11

回答ありがとうございます。 返信遅くなって申し訳ございません。 ログインの仕組みをもう一度確認してみたのですが、構造体に格納することは可読性の問題のようなので構造体を使用するのをやめました。Formをパースして、string型の変数に格納しデータベースにその情報があるかどうか確認するようにしました。 無事実装ができました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問