From 3db77684ecdcc4164f56ace1baa27975af538f4b Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Sun, 18 Oct 2020 20:31:58 +0300 Subject: [PATCH] add a very simple example on JWT and move the previous to the 'overview' sub folder --- HISTORY.md | 2 +- _examples/README.md | 4 +- _examples/auth/jwt/basic/main.go | 44 +++++++++++++++++++ _examples/auth/jwt/{ => overview}/README.md | 0 _examples/auth/jwt/{ => overview}/main.go | 0 .../{ => overview}/rsa_password_protected.key | 0 middleware/jwt/jwt.go | 15 +++++++ 7 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 _examples/auth/jwt/basic/main.go rename _examples/auth/jwt/{ => overview}/README.md (100%) rename _examples/auth/jwt/{ => overview}/main.go (100%) rename _examples/auth/jwt/{ => overview}/rsa_password_protected.key (100%) diff --git a/HISTORY.md b/HISTORY.md index 7e885aac..82990b49 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -29,7 +29,7 @@ The codebase for Dependency Injection, Internationalization and localization and ## Fixes and Improvements - A generic User interface, see the `Context.SetUser/User` methods in the New Context Methods section for more. In-short, the basicauth middleware's stored user can now be retrieved through `Context.User()` which provides more information than the native `ctx.Request().BasicAuth()` method one. Third-party authentication middleware creators can benefit of these two methods, plus the Logout below. -- A `Context.Logout` method is added, can be used to invalidate [basicauth](https://github.com/kataras/iris/blob/master/_examples/auth/basicauth/main.go) or [jwt](https://github.com/kataras/iris/blob/master/_examples/auth/jwt/main.go) client credentials. +- A `Context.Logout` method is added, can be used to invalidate [basicauth](https://github.com/kataras/iris/blob/master/_examples/auth/basicauth/main.go) or [jwt](https://github.com/kataras/iris/blob/master/_examples/auth/jwt/overview/main.go) client credentials. - Add the ability to [share functions](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-funcs) between handlers chain and add an [example](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-services) on sharing Go structures (aka services). - Add the new `Party.UseOnce` method to the `*Route` diff --git a/_examples/README.md b/_examples/README.md index 9383dd28..da8c458b 100644 --- a/_examples/README.md +++ b/_examples/README.md @@ -198,7 +198,9 @@ * Authentication, Authorization & Bot Detection * [Basic Authentication](auth/basicauth/main.go) * [CORS](auth/cors) - * [JWT](auth/jwt/main.go) + * JSON Web Tokens + * [Overview](auth/jwt/overview/main.go) + * [Basic](auth/jwt/basic/main.go) * [Refresh Token](auth/jwt/refresh-token/main.go) * [JWT (community edition)](https://github.com/iris-contrib/middleware/tree/v12/jwt/_example/main.go) * [OAUth2](auth/goth/main.go) diff --git a/_examples/auth/jwt/basic/main.go b/_examples/auth/jwt/basic/main.go new file mode 100644 index 00000000..f4b36699 --- /dev/null +++ b/_examples/auth/jwt/basic/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "time" + + "github.com/kataras/iris/v12" + "github.com/kataras/iris/v12/middleware/jwt" +) + +func main() { + app := iris.New() + // With AES-GCM (128) encryption: + // j := jwt.HMAC(15*time.Minute, "secret", "itsa16bytesecret") + // Without extra encryption, just the sign key: + j := jwt.HMAC(15*time.Minute, "secret") + + app.Get("/", generateToken(j)) + app.Get("/protected", j.VerifyMap(), protected) + + app.Listen(":8080") +} + +func generateToken(j *jwt.JWT) iris.Handler { + return func(ctx iris.Context) { + token, err := j.Token(iris.Map{ + "foo": "bar", + }) + if err != nil { + ctx.StopWithStatus(iris.StatusInternalServerError) + return + } + + ctx.HTML(`Token: ` + token + `

+ /secured?token=` + token + ``) + } +} + +func protected(ctx iris.Context) { + ctx.Writef("This is an authenticated request.\n\n") + + claims := jwt.Get(ctx).(iris.Map) + + ctx.Writef("foo=%s\n", claims["foo"]) +} diff --git a/_examples/auth/jwt/README.md b/_examples/auth/jwt/overview/README.md similarity index 100% rename from _examples/auth/jwt/README.md rename to _examples/auth/jwt/overview/README.md diff --git a/_examples/auth/jwt/main.go b/_examples/auth/jwt/overview/main.go similarity index 100% rename from _examples/auth/jwt/main.go rename to _examples/auth/jwt/overview/main.go diff --git a/_examples/auth/jwt/rsa_password_protected.key b/_examples/auth/jwt/overview/rsa_password_protected.key similarity index 100% rename from _examples/auth/jwt/rsa_password_protected.key rename to _examples/auth/jwt/overview/rsa_password_protected.key diff --git a/middleware/jwt/jwt.go b/middleware/jwt/jwt.go index f449383e..34ef36bc 100644 --- a/middleware/jwt/jwt.go +++ b/middleware/jwt/jwt.go @@ -246,6 +246,9 @@ func getenv(key string, def string) string { // // It panics on errors. // Use the `New` package-level function instead for more options. +// +// Example at: +// https://github.com/kataras/iris/tree/master/_examples/auth/jwt/overview/main.go func HMAC(maxAge time.Duration, keys ...string) *JWT { var defaultSignSecret, defaultEncSecret string @@ -767,8 +770,20 @@ func (j *JWT) Verify(newPtr func() interface{}, expections ...Expectation) conte } } +// VerifyMap is a shortcut of Verify with a function which will bind +// the claims to a standard Go map[string]interface{}. +func (j *JWT) VerifyMap(exceptions ...Expectation) context.Handler { + return j.Verify(func() interface{} { + return &context.Map{} + }) +} + // VerifyJSON works like `Verify` but instead it // binds its "newPtr" function to return a raw JSON message. +// It does NOT read the token from JSON by itself, +// to do that add the `FromJSON` to the Token Extractors. +// It's used to bind the claims in any value type on the next handler. +// // This allows the caller to bind this JSON message to any Go structure (or map). // This is useful when we can accept more than one // type of JWT token in the same request path,