diff --git a/_examples/auth/jwt/tutorial/README.md b/_examples/auth/jwt/tutorial/README.md index a5776223..5a52c56b 100644 --- a/_examples/auth/jwt/tutorial/README.md +++ b/_examples/auth/jwt/tutorial/README.md @@ -1,9 +1,15 @@ # Iris JWT Tutorial +This example show how to use JWT with domain-driven design pattern with Iris. There is also a simple Go client which describes how you can use Go to authorize a user and use the server's API. + +## Run the server + ```sh $ go run main.go ``` +## Authenticate, get the token + ```sh $ curl --location --request POST 'http://localhost:8080/signin' \ --header 'Content-Type: application/x-www-form-urlencoded' \ @@ -13,6 +19,8 @@ $ curl --location --request POST 'http://localhost:8080/signin' \ > $token ``` +## Get all TODOs for this User + ```sh $ curl --location --request GET 'http://localhost:8080/todos' \ --header 'Authorization: Bearer $token' @@ -20,6 +28,8 @@ $ curl --location --request GET 'http://localhost:8080/todos' \ > $todos ``` +## Get a specific User's TODO + ```sh $ curl --location --request GET 'http://localhost:8080/todos/$id' \ --header 'Authorization: Bearer $token' @@ -27,6 +37,8 @@ $ curl --location --request GET 'http://localhost:8080/todos/$id' \ > $todo ``` +## Get all TODOs for all Users (admin role) + ```sh $ curl --location --request GET 'http://localhost:8080/admin/todos' \ --header 'Authorization: Bearer $token' @@ -34,6 +46,8 @@ $ curl --location --request GET 'http://localhost:8080/admin/todos' \ > $todos ``` +## Create a new TODO + ```sh $ curl --location --request POST 'http://localhost:8080/todos' \ --header 'Authorization: Bearer $token' \ @@ -46,5 +60,3 @@ $ curl --location --request POST 'http://localhost:8080/todos' \ > Status Created > $todo ``` - -TODO: write the article on https://medium.com/@kataras, https://dev.to/kataras and linkedin first. diff --git a/_examples/dependency-injection/jwt/contrib/go.mod b/_examples/dependency-injection/jwt/contrib/go.mod index 990ef4e0..97b9162e 100644 --- a/_examples/dependency-injection/jwt/contrib/go.mod +++ b/_examples/dependency-injection/jwt/contrib/go.mod @@ -2,4 +2,6 @@ module github.com/kataras/iris/_examples/dependency-injection/jwt/contrib go 1.15 -require github.com/iris-contrib/middleware/jwt v0.0.0-20200810001613-32cf668f999f +require ( + github.com/iris-contrib/middleware/jwt v0.0.0-20201017024110-39b50ffeb885 +) diff --git a/_examples/dependency-injection/jwt/main.go b/_examples/dependency-injection/jwt/main.go index c705fac9..54c105cb 100644 --- a/_examples/dependency-injection/jwt/main.go +++ b/_examples/dependency-injection/jwt/main.go @@ -11,40 +11,59 @@ func main() { app := iris.New() app.ConfigureContainer(register) + // http://localhost:8080/authenticate + // http://localhost:8080/restricted app.Listen(":8080") } -func register(api *iris.APIContainer) { - j := jwt.HMAC(15*time.Minute, "secret", "secretforencrypt") +var ( + secret = []byte("secret") + signer = jwt.NewSigner(jwt.HS256, secret, 15*time.Minute) + verify = jwt.NewVerifier(jwt.HS256, secret, jwt.Expected{Issuer: "myapp"}).Verify(func() interface{} { + return new(userClaims) + }) +) - api.RegisterDependency(func(ctx iris.Context) (claims userClaims) { - if err := j.VerifyToken(ctx, &claims); err != nil { - ctx.StopWithError(iris.StatusUnauthorized, err) - return +func register(api *iris.APIContainer) { + // To register the middleware in the whole api container: + // api.Use(verify) + // Otherwise, protect routes when userClaims is expected on the functions input + // by calling the middleware manually, see below. + api.RegisterDependency(func(ctx iris.Context) (claims *userClaims) { + if ctx.Proceed(verify) { // the "verify" middleware will stop the execution if it's failed to verify the request. + // Map the input parameter of "restricted" function with the claims. + return jwt.Get(ctx).(*userClaims) } - return + return nil }) - api.Get("/authenticate", writeToken(j)) + api.Get("/authenticate", writeToken) api.Get("/restricted", restrictedPage) } type userClaims struct { - jwt.Claims - Username string + Username string `json:"username"` } -func writeToken(j *jwt.JWT) iris.Handler { - return func(ctx iris.Context) { - j.WriteToken(ctx, userClaims{ - Claims: j.Expiry(jwt.Claims{Issuer: "an-issuer"}), - Username: "kataras", - }) +func writeToken(ctx iris.Context) { + claims := userClaims{ + Username: "kataras", } + standardClaims := jwt.Claims{ + Issuer: "myapp", + } + + token, err := signer.Sign(claims, standardClaims) + if err != nil { + ctx.StopWithError(iris.StatusInternalServerError, err) + return + } + + ctx.Write(token) } -func restrictedPage(claims userClaims) string { +func restrictedPage(claims *userClaims) string { // userClaims.Username: kataras return "userClaims.Username: " + claims.Username }