3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go Signinしたときにtokenを作成する

Last updated at Posted at 2019-08-21

token作成やsessionの部分でつまずいたのでメモです。
SigninしたときにGo側でtokenを作成し、Javascriptのlocalstorageでtokenの情報を保持します。
データベースにaccountsテーブルがあり、email,password,nameなどその他諸々が入ってます。

サインイン画面

スクリーンショット 2019-08-21 13.01.04.png

Go

フレームワークとしてechoを使用しています。
トークンの中身はとりあえずaccount_idとトークンの有効期間を設定するやつです。

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

    h := &handler{
        DB: db,
    }
    return e
}

type token struct {
    AccountID uint
    jwt.StandardClaims
}

signin.go
    // 画面からメールアドレスとパスワードが送られてくるため、リクエストを受け取る構造体を用意してあげる
    type loginParam struct {
	Email    string `json:"email"`
	Password string `json:"password"`
    }

    func (h *handler) loginUser(c echo.Context) error {
	var params loginParam
	err := c.Bind(&params)
	if err != nil {
		return err
	}

    // リクエストとデータベースのemailが一致するレコードをセットする
	var account models.Account
	err = h.DB.Where("email = ?", params.Email).First(&account).Error
	if err != nil {
		return err
	}

    // リクエストされたemailをもつレコードがデータベースに存在しない場合のエラー処理
	if account.ID == 0 {
		return echo.ErrUnauthorized
	}

    // リクエストされたpasswordとデータベースのpasswordが一致しない時のエラー処理
	if params.Password != account.Password {
		return echo.ErrUnauthorized
	}

	// トークン作成
	claims := &token{
		AccountID: account.ID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * 72).Unix(),
		},
	}

	// 暗号化してtokenにしまう
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 生成された暗号を文字列としてキーをつけてtにしまう
	t, err := token.SignedString([]byte("hogehoge"))
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, map[string]string{"token": t})
}

React

作成したtokenはlocalstorageに保持します。
emailとpasswordだけを送るようにして、リクエストが通ったらlocalstorageにトークンをセットして、トップページに飛ばします。
通らなかった場合は、emailかpasswordが間違っているというエラー文を画面に表示します。

signin.js
handleSubmit() {
    return http
      .post('http://localhost:5000/login', {
        email: this.state.email,
        password: this.state.password
      })
      .then(response => {
        // 暗号化されたトークンをlocalStorageにabc_tokenというキーをつけてセット
        localStorage.setItem('abc_token', response.data.token);
        this.props.history.push(`/cust/toppage`)
        return response.data
      })
      .catch(error => {
        console.log(error)
        this.setState({
          errors: "メールアドレスもしくはパスワードに誤りがあります"
        })
      })
  }

リクエストを送るときに毎回headersにトークンを詰めなければいけないため、axiosを用いて、http.jsに切り出して呼び出す形にしています。

http.js
import axios from 'axios';

const API_HOST = process.env.REACT_APP_API_HOST || 'http://localhost:5000';
// localStorageからabc_tokenというキーでトークンをgetする
const http = axios.create({
  baseURL: API_HOST,
  headers: {
    Authorization: localStorage.getItem('abc_token') || ''
  }
});

export const defaultHttp = axios.create({
  headers: {
    Authorization: localStorage.getItem('abc_token') || ''
  }
});

export default http;

検証

abc_tokenというキーがついた、暗号化されたtokenが保持されているのが確認できます
スクリーンショット 2019-08-21 21.57.01.png

以上です。
今回はトークンを作成するだけだったのですが、tokenに紐づくデータをGETする方法
Go React トークンに紐づくユーザーの情報をGETする
新しく記事を更新しました!!
理解が足りていなくて抜け落ちているところがあるかもしれないので、コメントで教えていただけると幸いです。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?