Je suis en train de créer une API (avec go) et je travaille sur la partie session . Après des recherches sur les éléments à utiliser pour la session, j'ai trouvé JWT vraiment intéressant.
Cependant, je ne suis pas vraiment sûr de comprendre comment l'utiliser après quelques tutoriels ... C'est donc mon idée:
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/login", login)
router.HandleFunc("/logout", logout)
router.HandleFunc("/register", register)
http.ListenAndServe(":8080", router)
}
Une fois ces demandes traitées, je crée les différentes fonctions.
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?
*/
}
Beaucoup de tutoriels sur le web semblent très difficiles, mais je veux juste quelque chose de simple. Je veux juste qu'un package de descripteurs (code ci-dessus) qui fonctionne avec un package de services ait quelque chose comme une authentification par jeton de moteur.
Un deuxième point que je ne suis pas sûr de comprendre, c’est l’économie du jeton ... Si un utilisateur se connecte, quel serait le mieux? Chaque fois que l'utilisateur exécute son application, l'application se connecte elle-même et obtient un nouveau jeton à partir d'informations enregistrées (utilisateur/mot de passe) ou l'application sauvegarde-t-elle le jeton pour toujours? Et que dire du serveur, le jeton est-il géré et enregistré automatiquement avec JWT ou dois-je le mettre dans ma base de données SQL?
Merci pour votre aide!
EDIT 1
Je vous remercie ! Donc, après avoir lu votre réponse, j'ai encapsulé mon code (token.go) comme ça
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, ""
}
}
Cependant, j'ai eu l'erreur suivante: "token.go: undefined: myLookupKey" J'ai regardé sur Internet et j'ai trouvé une fonction encapsulée qui possède ce prototype:
func ExampleParse(myToken string, myLookupKey func(interface{}) (interface{}, error)) {
/* same code in my func parseToken() */
}
Alors, quelle est la différence entre ma fonction et celle-ci? Comment puis-je utiliser celui-ci?
Merci !
Pour commencer, vous devez importer une bibliothèque JWT à Golang (allez à github.com/dgrijalva/jwt-go). Vous pouvez trouver la documentation de cette bibliothèque dans le lien ci-dessous.
https://github.com/dgrijalva/jwt-go
Tout d'abord, vous devez créer un jeton
// 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)
Deuxièmement, analyser ce jeton
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(":(")
}
En outre, il existe quelques exemples d'utilisation de JWT dans GOlang comme ceci 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.")
}
}
Juste pour faire la mise à jour de la réponse @ massoud-afrashteh . Dans la version 3 de
// Set some claims
claims := make(jwt.MapClaims)
claims["foo"] = "bar"
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
token.Claims = claims
N'oubliez pas d'exécuter la commande go get github.com/dgrijalva/jwt-go
.
Une autre façon de créer plus simple:
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)
}