Go React  トークンに紐づくユーザーの情報をGETする

前回、 [Go Signinしたときにtokenを作成する](https://qiita.com/kibaa_go/items/a765af7b1b0546046381) でtokenを作成しlocalstorageに保持するところまで書きました。
今回は、その作成したトークンに紐づいたaccount(ユーザー)の情報をGETするまでを書いていきたいと思います。
GORMとechoを使用しています。

#Go
新しくJwtAuthというfunctionを作ります。

```Go:handler.go
func New(db *gorm.DB) http.Handler {
	e := echo.New()
	e.Use(middleware.CORS())

	h := &handler{
		DB: db,
	}
    // ここにJwtAuthと記述しないとうまくいかない
	e.GET("/account", h.getAccount, JwtAuth)

	return e
}

type token struct {
	AccountID uint
	jwt.StandardClaims
}

func JwtAuth(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		// Authorization(前の記事のhttp.jsに記述)からトークンをゲットしてauthHeaderにしまう
		authHeader := c.Request().Header.Get("Authorization")

		// トークンが空の場合、つまりログインしていない場合エラー処理
		if authHeader == "" {
			return c.JSON(http.StatusUnauthorized, map[string]string{"message": "Not Authorized"})
		}

		// 暗号化されたトークンを暗号化されていないものになおす
		var session token
		token, _ := jwt.ParseWithClaims(authHeader, &session, func(token *jwt.Token) (interface{}, error) {
			return []byte("hogehoge"), nil
		})

		if !token.Valid {
			return c.JSON(http.StatusUnauthorized, map[string]string{"message": "Not Authorized"})
		}

		if !time.Unix(session.StandardClaims.ExpiresAt, 0).After(time.Now()) {
			return c.JSON(http.StatusUnauthorized, map[string]string{"message": "Not Authorized"})
		}

		// sessionというキーをつけてトークンをセット
		c.Set("session", session)

		return next(c)
	}
}
```

トークンからaccountの情報をGETするための記述

```Go:account.go
type Param struct {
	Account models.Account         `json:"account"`
}

func (h *handler) getAccount(c echo.Context) error {
    // handler.goでセットしたsessionからtoken情報をGET
	session := c.Get("session").(token)

    // session.AccountIDとaccountsテーブルのidが一致するものをセットしてreturn
	var param Param
	err := h.DB.Where("id = ?", session.AccountID).First(&param.Account).Error
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, param)
}
```

#React
サインインしていることを前提として、お客様情報ページではaccount(ユーザー)の詳細を表示します。デフォルトでフォームにはaccountのデータを反映させたいので、今回は例としてnameを使います。
httpは[Go Signinしたときにtokenを作成する](https://qiita.com/kibaa_go/items/a765af7b1b0546046381) のhttp.jsからimportしてます！

```React:CustomerDetail.js
class CustmerDetail extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  componentDidMount() {
    return http
      .get('http://localhost:5000/account')
      .then(response => {
        this.setState({
          customer: response.data.account
        })
      })
      .catch(error => {
        console.log(error)
      })
  }

  render() {
    return (
        <div className="redister-header">
        // signinしてないとcustomerがsetStateされないので画面には何も表示されなくなる
        {this.state.customer ? (
          <input
            type="text"
            name="name"
            defaultValue={this.state.customer.name}
            size="30"
          />
         ) : null}
        </div>
    )
  }
}

export default CustmeDetail;
```

#検証
console.log(this.state.customer)で確認するとnameやemailなど情報がGETできていることが確認できます。
パスワードを暗号化していなくてすみません。。後々実装します。
<img width="535" alt="スクリーンショット 2019-08-26 19.56.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320179/acf6faa0-865b-a266-4cb0-b1f9b3507748.png">
フォームはこんな感じです。
<img width="412" alt="スクリーンショット 2019-08-26 20.23.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320179/dfc6f152-f192-4830-e06c-ecdb24fbeca0.png">

#まとめ
正直JwtAuthの中身の理解がまだ曖昧です。。
e.GET()中にJwtAuthを書かなくても、e.Use(JwtAuth)と書けば使えるらしいです。
理解が足りていない部分や省略して書いている部分がありますので、ご指摘いただけると幸いです。