Suche…


Einführung

JSON-Web-Token (JWTs) sind eine beliebte Methode, um Forderungen zwischen zwei Parteien sicher darzustellen. Bei der Entwicklung von Webanwendungen oder Anwendungsprogrammierschnittstellen ist es wichtig zu verstehen, wie mit ihnen gearbeitet wird.

Bemerkungen

context.Context und HTTP-Middleware sind außerhalb des Themas dieses Themas, aber dennoch sollten neugierige, wandernde Seelen https://github.com/goware/jwtauth , https://github.com/auth0/go-jwt- Middleware und https://github.com/dgrijalva/jwt-go .

Ein großes Lob an Dave Grijalva für seine erstaunliche Arbeit an go-jwt.

Analysieren und Validieren eines Tokens mithilfe der HMAC-Signaturmethode

// sample token string taken from the New example
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.u1riaD1rW97opCoAuRCTy4w58Br-Zk-bh7vLiRIsrpU"

// Parse takes the token string and a function for looking up the key. The latter is especially
// useful if you use multiple keys for your application.  The standard is to use 'kid' in the
// head of the token to identify which key to use, but the parsed token (head and claims) is provided
// to the callback, providing flexibility.
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
    // Don't forget to validate the alg is what you expect:
    if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
        return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
    }

    // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
    return hmacSampleSecret, nil
})

if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
    fmt.Println(claims["foo"], claims["nbf"])
} else {
    fmt.Println(err)
}

Ausgabe:

bar 1.4444784e+09

(Aus der Dokumentation , mit freundlicher Genehmigung von Dave Grijalva.)

Token mit einem benutzerdefinierten Anspruchstyp erstellen

Der StandardClaim ist in den benutzerdefinierten Typ eingebettet, um die einfache Kodierung, Analyse und Validierung von Standardansprüchen zu ermöglichen.

tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"

type MyCustomClaims struct {
    Foo string `json:"foo"`
    jwt.StandardClaims
}

// sample token is expired.  override time so it parses as valid
at(time.Unix(0, 0), func() {
    token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
        return []byte("AllYourBase"), nil
    })

    if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
        fmt.Printf("%v %v", claims.Foo, claims.StandardClaims.ExpiresAt)
    } else {
        fmt.Println(err)
    }
})

Ausgabe:

bar 15000

(Aus der Dokumentation , mit freundlicher Genehmigung von Dave Grijalva.)

Erstellen, Signieren und Codieren eines JWT-Tokens mithilfe der HMAC-Signaturmethode

// Create a new token object, specifying signing method and the claims
// you would like it to contain.
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    "foo": "bar",
    "nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
})

// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString(hmacSampleSecret)

fmt.Println(tokenString, err)

Ausgabe:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.u1riaD1rW97opCoAuRCTy4w58Br-Zk-bh7vLiRIsrpU <nil>

(Aus der Dokumentation , mit freundlicher Genehmigung von Dave Grijalva.)

Verwenden Sie den StandardClaims-Typ, um ein Token zu analysieren

Der StandardClaims Typ kann in Ihre benutzerdefinierten Typen eingebettet werden, um Standardvalidierungsfunktionen bereitzustellen. Sie können es alleine verwenden, aber es ist nicht möglich, andere Felder nach der Analyse abzurufen. Siehe das Beispiel für benutzerdefinierte Ansprüche zur beabsichtigten Verwendung.

mySigningKey := []byte("AllYourBase")

// Create the Claims
claims := &jwt.StandardClaims{
    ExpiresAt: 15000,
    Issuer:    "test",
}

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
ss, err := token.SignedString(mySigningKey)
fmt.Printf("%v %v", ss, err)

Ausgabe:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.QsODzZu3lUZMVdhbO76u3Jv02iYCvEHcYVUI1kOWEU0 <nil>

(Aus der Dokumentation , mit freundlicher Genehmigung von Dave Grijalva.)

Analysieren der Fehlertypen mit Bitfeldprüfungen

// Token from another example.  This token is expired
var tokenString = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
    return []byte("AllYourBase"), nil
})

if token.Valid {
    fmt.Println("You look nice today")
} else if ve, ok := err.(*jwt.ValidationError); ok {
    if ve.Errors&jwt.ValidationErrorMalformed != 0 {
        fmt.Println("That's not even a token")
    } else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
        // Token is either expired or not active yet
        fmt.Println("Timing is everything")
    } else {
        fmt.Println("Couldn't handle this token:", err)
    }
} else {
    fmt.Println("Couldn't handle this token:", err)
}

Ausgabe:

Timing is everything

(Aus der Dokumentation , mit freundlicher Genehmigung von Dave Grijalva.)

Token aus dem HTTP-Autorisierungsheader abrufen

type contextKey string

const (
    // JWTTokenContextKey holds the key used to store a JWT Token in the
    // context.
    JWTTokenContextKey contextKey = "JWTToken"

    // JWTClaimsContextKey holds the key used to store the JWT Claims in the
    // context.
    JWTClaimsContextKey contextKey = "JWTClaims"
)

// ToHTTPContext moves JWT token from request header to context.
func ToHTTPContext() http.RequestFunc {
    return func(ctx context.Context, r *stdhttp.Request) context.Context {
        token, ok := extractTokenFromAuthHeader(r.Header.Get("Authorization"))
        if !ok {
            return ctx
        }

        return context.WithValue(ctx, JWTTokenContextKey, token)
    }
}

(Von Go-Kit / Kit , mit freundlicher Genehmigung von Peter Bourgon)



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow