-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1662 from kataras/jwt-new-features
New JWT Middleware features and more
- Loading branch information
Showing
61 changed files
with
2,910 additions
and
1,391 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package main | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/kataras/iris/v12" | ||
"github.com/kataras/jwt" | ||
) | ||
|
||
/* | ||
Learn how to use any JWT 3rd-party package with Iris. | ||
In this example we use the kataras/jwt one. | ||
Install with: | ||
go get -u github.com/kataras/jwt | ||
Documentation: | ||
https://github.com/kataras/jwt#table-of-contents | ||
*/ | ||
|
||
// Replace with your own key and keep them secret. | ||
// The "signatureSharedKey" is used for the HMAC(HS256) signature algorithm. | ||
var signatureSharedKey = []byte("sercrethatmaycontainch@r32length") | ||
|
||
func main() { | ||
app := iris.New() | ||
|
||
app.Get("/", generateToken) | ||
app.Get("/protected", protected) | ||
|
||
app.Listen(":8080") | ||
} | ||
|
||
type fooClaims struct { | ||
Foo string `json:"foo"` | ||
} | ||
|
||
func generateToken(ctx iris.Context) { | ||
claims := fooClaims{ | ||
Foo: "bar", | ||
} | ||
|
||
// Sign and generate compact form token. | ||
token, err := jwt.Sign(jwt.HS256, signatureSharedKey, claims, jwt.MaxAge(10*time.Minute)) | ||
if err != nil { | ||
ctx.StopWithStatus(iris.StatusInternalServerError) | ||
return | ||
} | ||
|
||
tokenString := string(token) // or jwt.BytesToString | ||
ctx.HTML(`Token: ` + tokenString + `<br/><br/> | ||
<a href="/protected?token=` + tokenString + `">/protected?token=` + tokenString + `</a>`) | ||
} | ||
|
||
func protected(ctx iris.Context) { | ||
// Extract the token, e.g. cookie, Authorization: Bearer $token | ||
// or URL query. | ||
token := ctx.URLParam("token") | ||
// Verify the token. | ||
verifiedToken, err := jwt.Verify(jwt.HS256, signatureSharedKey, []byte(token)) | ||
if err != nil { | ||
ctx.StopWithStatus(iris.StatusUnauthorized) | ||
return | ||
} | ||
|
||
ctx.Writef("This is an authenticated request.\n\n") | ||
|
||
// Decode the custom claims. | ||
var claims fooClaims | ||
verifiedToken.Claims(&claims) | ||
|
||
// Just an example on how you can retrieve all the standard claims (set by jwt.MaxAge, "exp"). | ||
standardClaims := jwt.GetVerifiedToken(ctx).StandardClaims | ||
expiresAtString := standardClaims.ExpiresAt().Format(ctx.Application().ConfigurationReadOnly().GetTimeFormat()) | ||
timeLeft := standardClaims.Timeleft() | ||
|
||
ctx.Writef("foo=%s\nexpires at: %s\ntime left: %s\n", claims.Foo, expiresAtString, timeLeft) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package main | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/kataras/iris/v12" | ||
"github.com/kataras/iris/v12/middleware/jwt" | ||
"github.com/kataras/iris/v12/middleware/jwt/blocklist/redis" | ||
|
||
// Optionally to set token identifier. | ||
"github.com/google/uuid" | ||
) | ||
|
||
var ( | ||
signatureSharedKey = []byte("sercrethatmaycontainch@r32length") | ||
|
||
signer = jwt.NewSigner(jwt.HS256, signatureSharedKey, 15*time.Minute) | ||
verifier = jwt.NewVerifier(jwt.HS256, signatureSharedKey) | ||
) | ||
|
||
type userClaims struct { | ||
Username string `json:"username"` | ||
} | ||
|
||
func main() { | ||
app := iris.New() | ||
|
||
// IMPORTANT | ||
// | ||
// To use the in-memory blocklist just: | ||
// verifier.WithDefaultBlocklist() | ||
// To use a persistence blocklist, e.g. redis, | ||
// start your redis-server and: | ||
blocklist := redis.NewBlocklist() | ||
// To configure single client or a cluster one: | ||
// blocklist.ClientOptions.Addr = "127.0.0.1:6379" | ||
// blocklist.ClusterOptions.Addrs = []string{...} | ||
// To set a prefix for jwt ids: | ||
// blocklist.Prefix = "myapp-" | ||
// | ||
// To manually connect and check its error before continue: | ||
// err := blocklist.Connect() | ||
// By default the verifier will try to connect, if failed then it will throw http error. | ||
// | ||
// And then register it: | ||
verifier.Blocklist = blocklist | ||
verifyMiddleware := verifier.Verify(func() interface{} { | ||
return new(userClaims) | ||
}) | ||
|
||
app.Get("/", authenticate) | ||
|
||
protectedAPI := app.Party("/protected", verifyMiddleware) | ||
protectedAPI.Get("/", protected) | ||
protectedAPI.Get("/logout", logout) | ||
|
||
// http://localhost:8080 | ||
// http://localhost:8080/protected?token=$token | ||
// http://localhost:8080/logout?token=$token | ||
// http://localhost:8080/protected?token=$token (401) | ||
app.Listen(":8080") | ||
} | ||
|
||
func authenticate(ctx iris.Context) { | ||
claims := userClaims{ | ||
Username: "kataras", | ||
} | ||
|
||
// Generate JWT ID. | ||
random, err := uuid.NewRandom() | ||
if err != nil { | ||
ctx.StopWithError(iris.StatusInternalServerError, err) | ||
return | ||
} | ||
id := random.String() | ||
|
||
// Set the ID with the jwt.ID. | ||
token, err := signer.Sign(claims, jwt.ID(id)) | ||
|
||
if err != nil { | ||
ctx.StopWithError(iris.StatusInternalServerError, err) | ||
return | ||
} | ||
|
||
ctx.Write(token) | ||
} | ||
|
||
func protected(ctx iris.Context) { | ||
claims := jwt.Get(ctx).(*userClaims) | ||
|
||
// To the standard claims, e.g. the generated ID: | ||
// jwt.GetVerifiedToken(ctx).StandardClaims.ID | ||
|
||
ctx.WriteString(claims.Username) | ||
} | ||
|
||
func logout(ctx iris.Context) { | ||
ctx.Logout() | ||
|
||
ctx.Redirect("/", iris.StatusTemporaryRedirect) | ||
} |
Oops, something went wrong.