現在、(goを使用して)APIを作成しており、セッション部分に取り組んでいます。セッションに何を使用するかを調査した結果、JWTが非常に興味深いことがわかりました。
しかし、いくつかのチュートリアルの後、その使用方法を理解できるかどうかはよくわかりません。これが私のアイデアです:
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/login", login)
router.HandleFunc("/logout", logout)
router.HandleFunc("/register", register)
http.ListenAndServe(":8080", router)
}
これらの要求を処理した後、さまざまな機能を作成します。
func login(w http.ResponseWriter, r *http.Request) {
/*
Here I just have to search in my database (SQL, I know how to do it). If the user is registered, I create a token and give it to him, but how can I do it?
*/
}
func logout(w http.ResponseWriter, r *http.Request) {
/*
I get a token and stop/delete it?
*/
}
func register(w http.ResponseWriter, r *http.Request) {
/*
I search if the user isn't register and then, if it isn't, I create a user in the database (I know how to do it). I connect him but again, how to make a new token?
*/
}
ウェブ上の多くのチュートリアルは本当に難しいように思えますが、単純なものが欲しいだけです。サービスパッケージで動作するハンドルパッケージ(上記のコード)には、エンジントークン認証のようなものが必要です。
理解していない2番目のポイントは、トークンの保存です。ユーザーが自分自身を接続する場合、何が最適でしょうか?ユーザーがアプリを実行するたびに、アプリは自動的に接続し、保存された情報(ユーザー/パスワード)から新しいトークンを取得しますか、それともアプリはトークンを永久に保存しますか?サーバーについてはどうですか、トークンはJWTで自動的に管理および保存されますか、それともSQLデータベースに入れる必要がありますか?
助けてくれてありがとう !
編集1
ありがとうございました !だからあなたの答えを読んだ後、私はそれのように私のコード(token.go)をカプセル化しました
package services
import (
"fmt"
"github.com/dgrijalva/jwt-go"
"time"
"../models"
)
var tokenEncodeString string = "something"
func createToken(user models.User) (string, error) {
// create the token
token := jwt.New(jwt.SigningMethodHS256)
// set some claims
token.Claims["username"] = user.Username;
token.Claims["password"] = user.Password;
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
//Sign and get the complete encoded token as string
return (token.SignedString(tokenEncodeString))
}
func parseToken(unparsedToken string) (bool, string) {
token, err := jwt.Parse(unparsedToken, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return myLookupKey(token.Header["kid"]), nil
})
if err == nil && token.Valid {
return true, unparsedToken
} else {
return false, ""
}
}
しかし、次のエラーが発生しました: "token.go:undefined:myLookupKey"インターネットで調べたところ、このプロトタイプを持つカプセル化された関数が見つかりました。
func ExampleParse(myToken string, myLookupKey func(interface{}) (interface{}, error)) {
/* same code in my func parseToken() */
}
それで、私の機能とこれとの違いは何ですか?これはどのように使用できますか?
ありがとう!
開始するには、GolangでJWTライブラリをインポートする必要があります(github.com/dgrijalva/jwt-goにアクセスしてください)。そのライブラリのドキュメントは、以下のリンクにあります。
https://github.com/dgrijalva/jwt-go
まず、トークンを作成する必要があります
// Create the token
token := jwt.New(jwt.SigningMethodHS256)
// Set some claims
token.Claims["foo"] = "bar"
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
// Sign and get the complete encoded token as a string
tokenString, err := token.SignedString(mySigningKey)
次に、そのトークンを解析します
token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return myLookupKey(token.Header["kid"]), nil
})
if err == nil && token.Valid {
deliverGoodness("!")
} else {
deliverUtterRejection(":(")
}
また、このようなGOlangでのJWTの使用例がいくつかあります https://github.com/slok/go-jwt-example
EDIT-1
package main
import (
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
const (
mySigningKey = "WOW,MuchShibe,ToDogge"
)
func main() {
createdToken, err := ExampleNew([]byte(mySigningKey))
if err != nil {
fmt.Println("Creating token failed")
}
ExampleParse(createdToken, mySigningKey)
}
func ExampleNew(mySigningKey []byte) (string, error) {
// Create the token
token := jwt.New(jwt.SigningMethodHS256)
// Set some claims
token.Claims["foo"] = "bar"
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
// Sign and get the complete encoded token as a string
tokenString, err := token.SignedString(mySigningKey)
return tokenString, err
}
func ExampleParse(myToken string, myKey string) {
token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) {
return []byte(myKey), nil
})
if err == nil && token.Valid {
fmt.Println("Your token is valid. I like your style.")
} else {
fmt.Println("This token is terrible! I cannot accept this.")
}
}
@ massoud-afrashteh回答を更新するだけです。 jwt-goのバージョン3では、ハマグリを設定する必要があります
// Set some claims claims := make(jwt.MapClaims) claims["foo"] = "bar" claims["exp"] = time.Now().Add(time.Hour * 72).Unix() token.Claims = claims
go get github.com/dgrijalva/jwt-go
コマンドを実行することを忘れないでください。
より簡単に作成する別の方法:
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
})
tokenString, err := token.SignedString([]byte("your key"))
fmt.Println(tokenString, err)
func GenerateToken(mySigningKey []byte, username string) (string, error) {
// Create the token
token := jwt.New(jwt.SigningMethodRS512)
claims := make(jwt.MapClaims)
claims[collections.PARAM_USER_NAME] = username
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
token.Claims = claims
return token.SignedString(mySigningKey)
}