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

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

新規登録して質問してみよう
ただいま回答率
85.49%
JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Go

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

JSON

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

Webサーバー

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

4567閲覧

EOFエラーが出てJSONボディをパースできない

BraveDragon

総合スコア15

JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Go

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

JSON

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

Webサーバー

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2021/05/12 11:05

前提・実現したいこと

Goを利用してAPIサーバーを作成中です。
リクエストをjson形式で受け取り、その中にあるメールアドレスとパスワードを照合してDBにある時のみ認証を通す処理を書こうとしています。
ある程度書き上げた上で正しく実行できるか、実際にPostmanでリクエストを送ってテストしてみたのですが、実行すると

>go run main.go C:/Users/(ユーザー名)/Documents/Projects/handler/handlerutil/handlerutil.go:21: EOF

というエラーが発生しました。
原因を調べたところ、JSONボディのパースがうまくいっていないことが原因だと分かったのですが、解決方法が分かりません。
どうすればEOFエラーを解決して、正しく認証を通して意図したリクエストを送れるようになるでしょうか?

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

  • リクエストをjson形式で受け取り、その中にあるメールアドレスとパスワードを照合してDBにある時のみ認証を通す処理を書こうとしている
  • ある程度書き上げた上で正しく実行できるか、実際にリクエストを送ってテストしてみたところ、
>go run main.go C:/Users/(ユーザー名)/Documents/Project/handler/handlerutil/handlerutil.go:21: EOF

というエラーが発生した。

  • このエラーを解決し、正しく認証を通して意図したリクエストを送れるようにしたい。

該当のソースコード

handlerutil.goのソースコード:

Go

1package handlerutil 2 3import ( 4 "encoding/json" 5 "log" 6 "net/http" 7) 8 9//ParseJsonBody : JSONボディから必要なデータを取得. 10func ParseJsonBody(r *http.Request, decordtarget interface{}) error { 11 err := json.NewDecoder(r.Body).Decode(&decordtarget) 12 if err != nil { 13 return err 14 } else { 15 return nil 16 } 17} 18 19//ErrorLoggingAndWriteHeader : errのnilチェック+Log吐き+httpステータスをw.WriteHeader()する. 20func ErrorLoggingAndWriteHeader(w http.ResponseWriter, err error, httpStatus int) { 21 log.Println(err) 22 w.WriteHeader(httpStatus) 23 24}

userhandler.goのソースコード:

Go

1package userhandler 2 3import ( 4 "Project/controller/usercontroller" 5 "Project/model/usermodel" 6 "Project/handler/handlerutil" 7 "net/http" 8) 9 10//UserSignIn : ユーザーのサインイン処理を行う. 11func UserSignIn(w http.ResponseWriter, r *http.Request){ 12 loginUser := usermodel.User{} 13 //JSONボディから必要なデータを取得 14 err := handlerutil.ParseJsonBody(r, &loginUser) 15 if err != nil { 16 handlerutil.ErrorLoggingAndWriteHeader(w, err, http.StatusBadRequest) 17 return 18 } 19 20 //メールアドレスとパスワードを照合+DBにある時のみサインインを通す 21 user, err := usercontroller.UserAuthorization(loginUser.MailAddress, loginUser.PassWord) 22 if err != nil { 23 //メールアドレスとパスワードの組がDBになければエラーを返す 24 handlerutil.ErrorLoggingAndWriteHeader(w, err, http.StatusUnauthorized) 25 return 26 } 27 28 29} 30※usercontroller.UserAuthorization()はメールアドレスとパスワードを照合し、DBにある時のみサインインを通す関数。この関数でエラーが発生していないことは確認済み。

usermodel.goのソースコード:

Go

1package usermodel 2 3//User: ユーザー情報を管理. 4type User struct { 5 Id string `db:"ID, primarykey"` //ユーザーID 6 Name string `db:"name" json:"name"` //ユーザー名 7 MailAddress string `db:"mailAddress" json:"mailAddress"` //メールアドレス 8 PassWord string `db:"password" json:"passWord"` //パスワード 9}

リクエストとして送ったjsonボディ

json

1{ 2 "id": "189680eb-b2de-11eb-9e65-00d861e5f8f0", 3 "mailAddress": "DEF", 4 "passWord": "HIJ" 5}

usersテーブルの中身:

IDnamemailAddresspassword
14cae32b-b2f5-11eb-8fde-00d861e5f8f0DEF111222
189680eb-b2de-11eb-9e65-00d861e5f8f0ABCDEFHIJ

試したこと

エラーメッセージをよく読んで上で自分で色々と調べた結果、handlerutil.ParseJsonBody()に問題があることは突き止めたのですが、どう解決すれば良いか分かりません。

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

Goのバージョン:1.16
gorilla/muxのバージョン:v1.8.0
Postmanのバージョン:v8.3.1

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

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

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

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

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

guest

回答1

0

ベストアンサー

ちいさく切り出したコードでちゃんとデコードできているので、r.Bodyが何らかの理由でCloseされているのかもしれません。
https://play.golang.org/p/GojG2dea_uX

go

1package main 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9) 10 11const REQUEST = ` 12{ 13 "id": "189680eb-b2de-11eb-9e65-00d861e5f8f0", 14 "mailAddress": "DEF", 15 "passWord": "HIJ" 16} 17` 18 19type User struct { 20 Id string `db:"ID, primarykey"` //ユーザーID 21 Name string `db:"name" json:"name"` //ユーザー名 22 MailAddress string `db:"mailAddress" json:"mailAddress"` //メールアドレス 23 PassWord string `db:"password" json:"passWord"` //パスワード 24} 25 26func ParseJsonBody(r *http.Request, decordtarget interface{}) error { 27 err := json.NewDecoder(r.Body).Decode(&decordtarget) 28 if err != nil { 29 return err 30 } else { 31 return nil 32 } 33} 34 35func main() { 36 loginUser := User{} 37 dummyReq := &http.Request{Body: ioutil.NopCloser(bytes.NewBufferString(REQUEST))} 38 fmt.Println(ParseJsonBody(dummyReq, &loginUser)) 39 fmt.Println(loginUser) 40}

追記

質問にある以下の表示は問題解決に相応しくありません。それはログ出力を代行してしまっているからです。
(代行する関数の場所がわかったとしてもエラー発生源は分かりません)

C:/Users/(ユーザー名)/Documents/Project/handler/handlerutil/handlerutil.go:21:

また、エラーログ出力を代行する関数を起こす時にはセオリーがあって、以下の様にすると
ErrorLoggerラッパーを呼び出したコードの場所を表示することができます。
(これをしない場合、log機能はエラーを検出したところで使いましょう)

https://play.golang.org/p/655wZJE9_s6

go

1package main 2 3import ( 4 "fmt" 5 "log" 6 "runtime" 7) 8 9func ErrorLogger(err error) { 10 _, src, l, _ := runtime.Caller(1) 11 log.Printf("%s:%d %v", src, l, err) 12} 13 14func main() { 15 ErrorLogger(fmt.Errorf("failed")) 16}

投稿2021/05/12 12:19

編集2021/05/13 00:13
nobonobo

総合スコア3367

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

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

BraveDragon

2021/05/13 05:18

回答してくださり、誠にありがとうございます。 「r.Bodyが何らかの理由でCloseされているのかもしれません。」とのことですが、リクエストをGETメソッドで送っていることを失念しておりました。メールアドレスとパスワードをJSONボディからヘッダーに移し、その上でヘッダーからメールアドレスとパスワードを読み取るように処理を書き換えましたところ、無事にリクエストを処理できるようになりました。 ログ出力代行関数の書き方についても教えていただき、誠にありがとうございました。 ログを確認してもどこのエラーなのか分からず、困っていました。本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問