2016-03-26 18 views
9

私は現在APIを作っています(goと一緒に)、私はセッションの部分で作業しています。 セッションのために何を使うべきかを研究したところ、JWTは本当に興味深いものでした。Goと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データベースに入れなければなりませんか?

ありがとうございました!

EDIT 1

ありがとうございました! 「token.go:未定義:myLookupKey」だから私はあなたの答えを読んだ後、私は自分のコードをカプセル化(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, "" 
    } 
} 

は、しかし、私は次のエラーを得た 私は、インターネット上で見て、私が見つかりました。このプロトタイプを持つカプセル化された関数:

func ExampleParse(myToken string, myLookupKey func(interface{}) (interface{}, error)) { 
/* same code in my func parseToken() */ 
} 

私の関数とこれとの違いは何ですか?これをどうすれば使えますか?

ありがとうございます!

+0

クレームマップを使用したコード例は機能しません。 APIはその間に変更されている可能性があります。 – chmike

+0

私は正直に分かりません:/私はずっと前に、そして今日私は仕事を変えました。:/ – Emixam23

答えて

16

こんにちは、最初にGolang(github.com/dgrijalva/jwt-go)にJWTライブラリをインポートする必要があります。そのライブラリのドキュメントは、次のリンクにあります。

https://github.com/dgrijalva/jwt-go

まず、あなたはまた、このhttps://github.com/slok/go-jwt-example

ようGOlangで使用するJWTのためのいくつかの例がある

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(":(") 
} 

トークントークン

// 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) 

そして後にパースを作成する必要があります

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.") 
    } 
} 
+0

ありがとう、あなたの答えは赤で、自分の投稿を編集;) – Emixam23

+0

OKもう一度私の答えを確認してください。 –

+0

@MaximeGuittet真の答えだったら、それをチェックして質問を閉じてください。おかげで –