Using JWT with Iris

The Iris JWT middleware was designed with security, performance and simplicity in mind, it protects your tokens from critical vulnerabilities that you may find in other libraries. It is based on kataras/jwt package.

  1. package main
  2. import (
  3. "time"
  4. "github.com/kataras/iris/v12"
  5. "github.com/kataras/iris/v12/middleware/jwt"
  6. )
  7. var (
  8. sigKey = []byte("signature_hmac_secret_shared_key")
  9. encKey = []byte("GCM_AES_256_secret_shared_key_32")
  10. )
  11. type fooClaims struct {
  12. Foo string `json:"foo"`
  13. }
  14. func main() {
  15. app := iris.New()
  16. signer := jwt.NewSigner(jwt.HS256, sigKey, 10*time.Minute)
  17. // Enable payload encryption with:
  18. // signer.WithEncryption(encKey, nil)
  19. app.Get("/", generateToken(signer))
  20. verifier := jwt.NewVerifier(jwt.HS256, sigKey)
  21. // Enable server-side token block feature (even before its expiration time):
  22. verifier.WithDefaultBlocklist()
  23. // Enable payload decryption with:
  24. // verifier.WithDecryption(encKey, nil)
  25. verifyMiddleware := verifier.Verify(func() interface{} {
  26. return new(fooClaims)
  27. })
  28. protectedAPI := app.Party("/protected")
  29. // Register the verify middleware to allow access only to authorized clients.
  30. protectedAPI.Use(verifyMiddleware)
  31. // ^ or UseRouter(verifyMiddleware) to disallow unauthorized http error handlers too.
  32. protectedAPI.Get("/", protected)
  33. // Invalidate the token through server-side, even if it's not expired yet.
  34. protectedAPI.Get("/logout", logout)
  35. // http://localhost:8080
  36. // http://localhost:8080/protected?token=$token (or Authorization: Bearer $token)
  37. // http://localhost:8080/protected/logout?token=$token
  38. // http://localhost:8080/protected?token=$token (401)
  39. app.Listen(":8080")
  40. }
  41. func generateToken(signer *jwt.Signer) iris.Handler {
  42. return func(ctx iris.Context) {
  43. claims := fooClaims{Foo: "bar"}
  44. token, err := signer.Sign(claims)
  45. if err != nil {
  46. ctx.StopWithStatus(iris.StatusInternalServerError)
  47. return
  48. }
  49. ctx.Write(token)
  50. }
  51. }
  52. func protected(ctx iris.Context) {
  53. // Get the verified and decoded claims.
  54. claims := jwt.Get(ctx).(*fooClaims)
  55. // Optionally, get token information if you want to work with them.
  56. // Just an example on how you can retrieve all the standard claims (set by signer's max age, "exp").
  57. standardClaims := jwt.GetVerifiedToken(ctx).StandardClaims
  58. expiresAtString := standardClaims.ExpiresAt().Format(ctx.Application().ConfigurationReadOnly().GetTimeFormat())
  59. timeLeft := standardClaims.Timeleft()
  60. ctx.Writef("foo=%s\nexpires at: %s\ntime left: %s\n", claims.Foo, expiresAtString, timeLeft)
  61. }
  62. func logout(ctx iris.Context) {
  63. err := ctx.Logout()
  64. if err != nil {
  65. ctx.WriteString(err.Error())
  66. } else {
  67. ctx.Writef("token invalidated, a new token is required to access the protected API")
  68. }
  69. }

Learn about refresh tokens, blocklist and more at: _examples/auth/jwt.