teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

トークンの生成方法を追加

2021/03/01 00:49

投稿

BraveDragon
BraveDragon

スコア15

title CHANGED
File without changes
body CHANGED
@@ -13,8 +13,91 @@
13
13
  > 3. 認証トークンには有効期限が設定されている。トークンの有効期限が切れた場合、更新しなければならないと思うのだが、更新の処理はどうすればよいのか。
14
14
 
15
15
  - 上記の1. 2. 3.の問題を解決し、認証トークンとリクエストヘッダ内のx-tokenの照合処理を完成させたい。
16
+ - トークンの生成方法は以下の通りとなる。
17
+ 0. 新規ユーザー登録時、ユーザー名をパスパラメーターから取得する。
18
+ 0. ユーザー名とは別に、ユーザーIDをUUIDで生成する。生成にはUUIDを扱うライブラリであるgoogle/uuidを使用する。
19
+ 0. トークンの有効期限を設定するため、現在の時刻を取得する。
20
+ 0. ユーザーIDをシードとして秘密鍵を生成。
21
+ 0. PASETOを扱うライブラリであるo1egl/pasetoを利用してPASETO用のトークンペイロードクレーム(token payload claim)を生成する。この時、トークンの有効期限を3.で取得した現在時刻から30分後までとする。
22
+ 0. footerに文字列"FOOTER"を設定する。
23
+ 0. 秘密鍵、トークンペイロードクレーム、footerを元に認証トークンを生成する。
24
+ 0. ユーザー情報を管理するDBのテーブルであるUserテーブルをマッピングした構造体UserにユーザーID、ユーザー名、認証トークンを格納し、それをDBに追加して反映させる。・
16
25
 
26
+ - 以上の処理のソースコードは以下の通りとなる。
27
+ ```Go
28
+ package main
17
29
 
30
+ import (
31
+ "database/sql"
32
+ "net/http"
33
+
34
+ "crypto/ed25519"
35
+ "encoding/hex"
36
+ "time"
37
+
38
+ "github.com/go-gorp/gorp"
39
+ "github.com/google/uuid"
40
+ "github.com/gorilla/mux"
41
+ "github.com/gorilla/schema"
42
+ "github.com/o1egl/paseto"
43
+ )
44
+
45
+ //User : ユーザー情報を管理
46
+ type User struct {
47
+ id string `db:"ID, primarykey` //ユーザーID
48
+ name string `db:"name"` //ユーザー名
49
+ token string `db:"token"` //認証トークン
50
+
51
+ }
52
+
53
+ //DB に接続
54
+ var DB, _ = sql.Open("mysql", "root:@APIDB")
55
+ var DBMap = &gorp.DbMap{Db: DB, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
56
+
57
+ //ユーザー作成を行う
58
+ func userCreate(w http.ResponseWriter, r *http.Request) {
59
+ //パスパラメーターから新規ユーザー名を取得
60
+ value := mux.Vars(r)
61
+ w.WriteHeader(http.StatusOK)
62
+
63
+ //IDはUUIDで生成
64
+ UUID, _ := uuid.NewUUID()
65
+
66
+ now := time.Now()
67
+ //ここから認証トークン生成部
68
+ //ユーザーIDから秘密鍵生成用のシードを生成
69
+ b, _ := hex.DecodeString(newUser.id)
70
+ privateKey := ed25519.PrivateKey(b)
71
+ jsonToken := paseto.JSONToken{
72
+ Audience: "Audience",
73
+ Issuer: "Issuer",
74
+ Subject: "WebAPI",
75
+ Jti: "UUID",
76
+ Expiration: time.Now().Add(30 * time.Minute),
77
+ IssuedAt: now,
78
+ NotBefore: now,
79
+ }
80
+
81
+ jsonToken.Set("KEY", "VALUE")
82
+ footer := "FOOTER"
83
+ tokenCreator := paseto.NewV2()
84
+ //トークンを生成
85
+ token, _ := tokenCreator.Sign(privateKey, jsonToken, footer)
86
+
87
+ //新規ユーザー
88
+ newUser := User{}
89
+ newUser.name = value["name"]
90
+ newUser.id = UUID.String()
91
+ newUser.token = token
92
+ //DBに追加+反映
93
+ dbHandler, _ := DBMap.Begin()
94
+ dbHandler.Insert(newUser)
95
+ dbHandler.Commit()
96
+
97
+ }
98
+ ```
99
+
100
+
18
101
  ### 試したこと
19
102
  以下のサイトを参考にすることで、認証トークンの作り方やgorillaの使い方はだいたい分かりましたが、現在私がやろうとしていることのやり方が分かりません。
20
103
  [goで作るAPIのセキュリティを考えた - Qiita](https://qiita.com/GpAraki/items/801cb4654ce109d49ec9)