前回、 Go Signinしたときにtokenを作成する でtokenを作成しlocalstorageに保持するところまで書きました。
今回は、その作成したトークンに紐づいたaccount(ユーザー)の情報をGETするまでを書いていきたいと思います。
GORMとechoを使用しています。
Go
新しくJwtAuthというfunctionを作ります。
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するための記述
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(¶m.Account).Error
if err != nil {
return err
}
return c.JSON(http.StatusOK, param)
}
React
サインインしていることを前提として、お客様情報ページではaccount(ユーザー)の詳細を表示します。デフォルトでフォームにはaccountのデータを反映させたいので、今回は例としてnameを使います。
httpはGo Signinしたときにtokenを作成する のhttp.jsからimportしてます!
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できていることが確認できます。
パスワードを暗号化していなくてすみません。。後々実装します。
フォームはこんな感じです。
まとめ
正直JwtAuthの中身の理解がまだ曖昧です。。
e.GET()中にJwtAuthを書かなくても、e.Use(JwtAuth)と書けば使えるらしいです。
理解が足りていない部分や省略して書いている部分がありますので、ご指摘いただけると幸いです。