mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
add experimental handlers examples
Former-commit-id: 8d8a0d15afce2554dc5926f6b9bd9c42cb95dad0
This commit is contained in:
parent
db433f7dca
commit
a7635afe62
|
@ -253,6 +253,7 @@ You can serve [quicktemplate](https://github.com/valyala/quicktemplate) and [her
|
||||||
### ORM
|
### ORM
|
||||||
|
|
||||||
- [Using xorm(Mysql, MyMysql, Postgres, Tidb, **SQLite**, MsSql, MsSql, Oracle)](orm/xorm/main.go)
|
- [Using xorm(Mysql, MyMysql, Postgres, Tidb, **SQLite**, MsSql, MsSql, Oracle)](orm/xorm/main.go)
|
||||||
|
- [Using gorm](orm/gorm/main.go)
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
||||||
|
|
5
_examples/experimental-handlers/README.md
Normal file
5
_examples/experimental-handlers/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Install iris-contrib/middleware
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ go get -u github.com/iris-contrib/middleware/...
|
||||||
|
```
|
|
@ -0,0 +1,14 @@
|
||||||
|
[request_definition]
|
||||||
|
r = sub, obj, act
|
||||||
|
|
||||||
|
[policy_definition]
|
||||||
|
p = sub, obj, act
|
||||||
|
|
||||||
|
[role_definition]
|
||||||
|
g = _, _
|
||||||
|
|
||||||
|
[policy_effect]
|
||||||
|
e = some(where (p.eft == allow))
|
||||||
|
|
||||||
|
[matchers]
|
||||||
|
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
|
|
@ -0,0 +1,5 @@
|
||||||
|
p, alice, /dataset1/*, GET
|
||||||
|
p, alice, /dataset1/resource1, POST
|
||||||
|
p, bob, /dataset2/resource1, *
|
||||||
|
p, bob, /dataset2/resource2, GET
|
||||||
|
p, bob, /dataset2/folder1/*, POST
|
|
43
_examples/experimental-handlers/casbin/middleware/main.go
Normal file
43
_examples/experimental-handlers/casbin/middleware/main.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/casbin/casbin/v2"
|
||||||
|
cm "github.com/iris-contrib/middleware/casbin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// $ go get github.com/casbin/casbin/v2
|
||||||
|
// $ go run main.go
|
||||||
|
|
||||||
|
// Enforcer maps the model and the policy for the casbin service, we use this variable on the main_test too.
|
||||||
|
var Enforcer, _ = casbin.NewEnforcer("casbinmodel.conf", "casbinpolicy.csv")
|
||||||
|
|
||||||
|
func newApp() *iris.Application {
|
||||||
|
casbinMiddleware := cm.New(Enforcer)
|
||||||
|
|
||||||
|
app := iris.New()
|
||||||
|
app.Use(casbinMiddleware.ServeHTTP)
|
||||||
|
|
||||||
|
app.Get("/", hi)
|
||||||
|
|
||||||
|
app.Get("/dataset1/{p:path}", hi) // p, alice, /dataset1/*, GET
|
||||||
|
|
||||||
|
app.Post("/dataset1/resource1", hi)
|
||||||
|
|
||||||
|
app.Get("/dataset2/resource2", hi)
|
||||||
|
app.Post("/dataset2/folder1/{p:path}", hi)
|
||||||
|
|
||||||
|
app.Any("/dataset2/resource1", hi)
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := newApp()
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func hi(ctx iris.Context) {
|
||||||
|
ctx.Writef("Hello %s", cm.Username(ctx.Request()))
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/httptest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCasbinMiddleware(t *testing.T) {
|
||||||
|
app := newApp()
|
||||||
|
e := httptest.New(t, app, httptest.Debug(false))
|
||||||
|
|
||||||
|
type ttcasbin struct {
|
||||||
|
username string
|
||||||
|
path string
|
||||||
|
method string
|
||||||
|
status int
|
||||||
|
}
|
||||||
|
|
||||||
|
tt := []ttcasbin{
|
||||||
|
{"alice", "/dataset1/resource1", "GET", 200},
|
||||||
|
{"alice", "/dataset1/resource1", "POST", 200},
|
||||||
|
{"alice", "/dataset1/resource2", "GET", 200},
|
||||||
|
{"alice", "/dataset1/resource2", "POST", 404},
|
||||||
|
|
||||||
|
{"bob", "/dataset2/resource1", "GET", 200},
|
||||||
|
{"bob", "/dataset2/resource1", "POST", 200},
|
||||||
|
{"bob", "/dataset2/resource1", "DELETE", 200},
|
||||||
|
{"bob", "/dataset2/resource2", "GET", 200},
|
||||||
|
{"bob", "/dataset2/resource2", "POST", 404},
|
||||||
|
{"bob", "/dataset2/resource2", "DELETE", 404},
|
||||||
|
|
||||||
|
{"bob", "/dataset2/folder1/item1", "GET", 404},
|
||||||
|
{"bob", "/dataset2/folder1/item1", "POST", 200},
|
||||||
|
{"bob", "/dataset2/folder1/item1", "DELETE", 404},
|
||||||
|
{"bob", "/dataset2/folder1/item2", "GET", 404},
|
||||||
|
{"bob", "/dataset2/folder1/item2", "POST", 200},
|
||||||
|
{"bob", "/dataset2/folder1/item2", "DELETE", 404},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tt {
|
||||||
|
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(e *httptest.Expect, method, path, username string, status int) {
|
||||||
|
e.Request(method, path).WithBasicAuth(username, "password").Expect().Status(status)
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
[request_definition]
|
||||||
|
r = sub, obj, act
|
||||||
|
|
||||||
|
[policy_definition]
|
||||||
|
p = sub, obj, act
|
||||||
|
|
||||||
|
[role_definition]
|
||||||
|
g = _, _
|
||||||
|
|
||||||
|
[policy_effect]
|
||||||
|
e = some(where (p.eft == allow))
|
||||||
|
|
||||||
|
[matchers]
|
||||||
|
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
|
|
@ -0,0 +1,7 @@
|
||||||
|
p, alice, /dataset1/*, GET
|
||||||
|
p, alice, /dataset1/resource1, POST
|
||||||
|
p, bob, /dataset2/resource1, *
|
||||||
|
p, bob, /dataset2/resource2, GET
|
||||||
|
p, bob, /dataset2/folder1/*, POST
|
||||||
|
p, dataset1_admin, /dataset1/*, *
|
||||||
|
g, cathrin, dataset1_admin
|
|
43
_examples/experimental-handlers/casbin/wrapper/main.go
Normal file
43
_examples/experimental-handlers/casbin/wrapper/main.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/casbin/casbin/v2"
|
||||||
|
cm "github.com/iris-contrib/middleware/casbin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// $ go get github.com/casbin/casbin
|
||||||
|
// $ go run main.go
|
||||||
|
|
||||||
|
// Enforcer maps the model and the policy for the casbin service, we use this variable on the main_test too.
|
||||||
|
var Enforcer, _ = casbin.NewEnforcer("casbinmodel.conf", "casbinpolicy.csv")
|
||||||
|
|
||||||
|
func newApp() *iris.Application {
|
||||||
|
casbinMiddleware := cm.New(Enforcer)
|
||||||
|
|
||||||
|
app := iris.New()
|
||||||
|
app.WrapRouter(casbinMiddleware.Wrapper())
|
||||||
|
|
||||||
|
app.Get("/", hi)
|
||||||
|
|
||||||
|
app.Any("/dataset1/{p:path}", hi) // p, dataset1_admin, /dataset1/*, * && p, alice, /dataset1/*, GET
|
||||||
|
|
||||||
|
app.Post("/dataset1/resource1", hi)
|
||||||
|
|
||||||
|
app.Get("/dataset2/resource2", hi)
|
||||||
|
app.Post("/dataset2/folder1/{p:path}", hi)
|
||||||
|
|
||||||
|
app.Any("/dataset2/resource1", hi)
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := newApp()
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func hi(ctx iris.Context) {
|
||||||
|
ctx.Writef("Hello %s", cm.Username(ctx.Request()))
|
||||||
|
}
|
79
_examples/experimental-handlers/casbin/wrapper/main_test.go
Normal file
79
_examples/experimental-handlers/casbin/wrapper/main_test.go
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/httptest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCasbinWrapper(t *testing.T) {
|
||||||
|
app := newApp()
|
||||||
|
e := httptest.New(t, app, httptest.Debug(true))
|
||||||
|
|
||||||
|
type ttcasbin struct {
|
||||||
|
username string
|
||||||
|
path string
|
||||||
|
method string
|
||||||
|
status int
|
||||||
|
}
|
||||||
|
|
||||||
|
tt := []ttcasbin{
|
||||||
|
{"alice", "/dataset1/resource1", "GET", 200},
|
||||||
|
{"alice", "/dataset1/resource1", "POST", 200},
|
||||||
|
{"alice", "/dataset1/resource2", "GET", 200},
|
||||||
|
{"alice", "/dataset1/resource2", "POST", 403},
|
||||||
|
|
||||||
|
{"bob", "/dataset2/resource1", "GET", 200},
|
||||||
|
{"bob", "/dataset2/resource1", "POST", 200},
|
||||||
|
{"bob", "/dataset2/resource1", "DELETE", 200},
|
||||||
|
{"bob", "/dataset2/resource2", "GET", 200},
|
||||||
|
{"bob", "/dataset2/resource2", "POST", 403},
|
||||||
|
{"bob", "/dataset2/resource2", "DELETE", 403},
|
||||||
|
|
||||||
|
{"bob", "/dataset2/folder1/item1", "GET", 403},
|
||||||
|
{"bob", "/dataset2/folder1/item1", "POST", 200},
|
||||||
|
{"bob", "/dataset2/folder1/item1", "DELETE", 403},
|
||||||
|
{"bob", "/dataset2/folder1/item2", "GET", 403},
|
||||||
|
{"bob", "/dataset2/folder1/item2", "POST", 200},
|
||||||
|
{"bob", "/dataset2/folder1/item2", "DELETE", 403},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tt {
|
||||||
|
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
println("ADMIN ROLES")
|
||||||
|
ttAdmin := []ttcasbin{
|
||||||
|
{"cathrin", "/dataset1/item", "GET", 200},
|
||||||
|
{"cathrin", "/dataset1/item", "POST", 200},
|
||||||
|
{"cathrin", "/dataset1/item", "DELETE", 200},
|
||||||
|
{"cathrin", "/dataset2/item", "GET", 403},
|
||||||
|
{"cathrin", "/dataset2/item", "POST", 403},
|
||||||
|
{"cathrin", "/dataset2/item", "DELETE", 403},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range ttAdmin {
|
||||||
|
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
println("ADMIN ROLE FOR cathrin DELETED")
|
||||||
|
Enforcer.DeleteRolesForUser("cathrin")
|
||||||
|
|
||||||
|
ttAdminDeleted := []ttcasbin{
|
||||||
|
{"cathrin", "/dataset1/item", "GET", 403},
|
||||||
|
{"cathrin", "/dataset1/item", "POST", 403},
|
||||||
|
{"cathrin", "/dataset1/item", "DELETE", 403},
|
||||||
|
{"cathrin", "/dataset2/item", "GET", 403},
|
||||||
|
{"cathrin", "/dataset2/item", "POST", 403},
|
||||||
|
{"cathrin", "/dataset2/item", "DELETE", 403},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range ttAdminDeleted {
|
||||||
|
check(e, tt.method, tt.path, tt.username, tt.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(e *httptest.Expect, method, path, username string, status int) {
|
||||||
|
e.Request(method, path).WithBasicAuth(username, "password").Expect().Status(status)
|
||||||
|
}
|
50
_examples/experimental-handlers/cloudwatch/simple/main.go
Normal file
50
_examples/experimental-handlers/cloudwatch/simple/main.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||||
|
cw "github.com/iris-contrib/middleware/cloudwatch"
|
||||||
|
)
|
||||||
|
|
||||||
|
// $ go get github.com/aws/aws-sdk-go/...
|
||||||
|
// $ go run main.go
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
app.Use(cw.New("us-east-1", "test").ServeHTTP)
|
||||||
|
|
||||||
|
app.Get("/", func(ctx iris.Context) {
|
||||||
|
put := cw.GetPutFunc(ctx)
|
||||||
|
|
||||||
|
put([]*cloudwatch.MetricDatum{
|
||||||
|
{
|
||||||
|
MetricName: aws.String("MyMetric"),
|
||||||
|
Dimensions: []*cloudwatch.Dimension{
|
||||||
|
{
|
||||||
|
Name: aws.String("ThingOne"),
|
||||||
|
Value: aws.String("something"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: aws.String("ThingTwo"),
|
||||||
|
Value: aws.String("other"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Timestamp: aws.Time(time.Now()),
|
||||||
|
Unit: aws.String("Count"),
|
||||||
|
Value: aws.Float64(42),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx.StatusCode(iris.StatusOK)
|
||||||
|
ctx.Text("success!\n")
|
||||||
|
})
|
||||||
|
|
||||||
|
// http://localhost:8080
|
||||||
|
// should give: NoCredentialProviders
|
||||||
|
// which is correct, you have to authorize your aws, we asumme that you know how to.
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
38
_examples/experimental-handlers/cors/simple/client/main.go
Normal file
38
_examples/experimental-handlers/cors/simple/client/main.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NOTE: THIS IS OPTIONALLY.
|
||||||
|
// It is just an example of communication between cors/simple/main.go and your app
|
||||||
|
// based on issues that beginners had with it.
|
||||||
|
// You should use your own favourite library for HTTP requests (any programming language ofc).
|
||||||
|
//
|
||||||
|
// Replace the '8fc93b1c.ngrok.io' with a domain which
|
||||||
|
// exposes the cors/simple/main.go server side.
|
||||||
|
const url = "http://8fc93b1c.ngrok.io/api/v1/mailer"
|
||||||
|
|
||||||
|
var clientSide = []byte(`<script type="text/javascript">
|
||||||
|
fetch("` + url + `", {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Access-Control-Allow-Origin": "*"
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
mode: "cors",
|
||||||
|
body: JSON.stringify({ email: "mymail@mail.com" }),
|
||||||
|
});
|
||||||
|
</script>`)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
app.Get("/", func(ctx iris.Context) {
|
||||||
|
ctx.Write(clientSide)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Start and navigate to http://localhost:8080
|
||||||
|
// and go to the previous terminal of your running cors/simple/main.go server
|
||||||
|
// and see the logs.
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
54
_examples/experimental-handlers/cors/simple/main.go
Normal file
54
_examples/experimental-handlers/cors/simple/main.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
crs := func(ctx iris.Context) {
|
||||||
|
ctx.Header("Access-Control-Allow-Origin", "*")
|
||||||
|
ctx.Header("Access-Control-Allow-Credentials", "true")
|
||||||
|
ctx.Header("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type")
|
||||||
|
ctx.Next()
|
||||||
|
} // or "github.com/iris-contrib/middleware/cors"
|
||||||
|
|
||||||
|
v1 := app.Party("/api/v1", crs).AllowMethods(iris.MethodOptions) // <- important for the preflight.
|
||||||
|
{
|
||||||
|
v1.Post("/mailer", func(ctx iris.Context) {
|
||||||
|
var any iris.Map
|
||||||
|
err := ctx.ReadJSON(&any)
|
||||||
|
if err != nil {
|
||||||
|
ctx.WriteString(err.Error())
|
||||||
|
ctx.StatusCode(iris.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Application().Logger().Infof("received %#+v", any)
|
||||||
|
})
|
||||||
|
|
||||||
|
v1.Get("/home", func(ctx iris.Context) {
|
||||||
|
ctx.WriteString("Hello from /home")
|
||||||
|
})
|
||||||
|
v1.Get("/about", func(ctx iris.Context) {
|
||||||
|
ctx.WriteString("Hello from /about")
|
||||||
|
})
|
||||||
|
v1.Post("/send", func(ctx iris.Context) {
|
||||||
|
ctx.WriteString("sent")
|
||||||
|
})
|
||||||
|
v1.Put("/send", func(ctx iris.Context) {
|
||||||
|
ctx.WriteString("updated")
|
||||||
|
})
|
||||||
|
v1.Delete("/send", func(ctx iris.Context) {
|
||||||
|
ctx.WriteString("deleted")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// iris.WithoutPathCorrectionRedirection | iris#Configuration.DisablePathCorrectionRedirection:
|
||||||
|
// CORS needs the allow origin headers in the redirect response as well, we have a solution for this:
|
||||||
|
// If you use iris >= v11.0.4 then add the `app.Run(..., iris.WithoutPathCorrectionRedirection)`
|
||||||
|
// on the server side if you wish
|
||||||
|
// to directly fire the handler instead of redirection (which is the default behavior)
|
||||||
|
// on request paths like "/v1/mailer/" when "/v1/mailer" route handler is registered.
|
||||||
|
app.Run(iris.Addr(":80"), iris.WithoutPathCorrectionRedirection)
|
||||||
|
}
|
55
_examples/experimental-handlers/csrf/main.go
Normal file
55
_examples/experimental-handlers/csrf/main.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// This middleware provides Cross-Site Request Forgery
|
||||||
|
// protection.
|
||||||
|
//
|
||||||
|
// It securely generates a masked (unique-per-request) token that
|
||||||
|
// can be embedded in the HTTP response (e.g. form field or HTTP header).
|
||||||
|
// The original (unmasked) token is stored in the session, which is inaccessible
|
||||||
|
// by an attacker (provided you are using HTTPS). Subsequent requests are
|
||||||
|
// expected to include this token, which is compared against the session token.
|
||||||
|
// Requests that do not provide a matching token are served with a HTTP 403
|
||||||
|
// 'Forbidden' error response.
|
||||||
|
package main
|
||||||
|
|
||||||
|
// $ go get -u github.com/iris-contrib/middleware/...
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/iris-contrib/middleware/csrf"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
app.RegisterView(iris.HTML("./views", ".html"))
|
||||||
|
// Note that the authentication key provided should be 32 bytes
|
||||||
|
// long and persist across application restarts.
|
||||||
|
protect := csrf.Protect([]byte("9AB0F421E53A477C084477AEA06096F5"),
|
||||||
|
csrf.Secure(false)) // Defaults to true, but pass `false` while no https (devmode).
|
||||||
|
|
||||||
|
users := app.Party("/user", protect)
|
||||||
|
{
|
||||||
|
users.Get("/signup", getSignupForm)
|
||||||
|
// // POST requests without a valid token will return a HTTP 403 Forbidden.
|
||||||
|
users.Post("/signup", postSignupForm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: http://localhost:8080/user/signup
|
||||||
|
// POST: http://localhost:8080/user/signup
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSignupForm(ctx iris.Context) {
|
||||||
|
// views/user/signup.html just needs a {{ .csrfField }} template tag for
|
||||||
|
// csrf.TemplateField to inject the CSRF token into. Easy!
|
||||||
|
ctx.ViewData(csrf.TemplateTag, csrf.TemplateField(ctx))
|
||||||
|
ctx.View("user/signup.html")
|
||||||
|
|
||||||
|
// We could also retrieve the token directly from csrf.Token(ctx) and
|
||||||
|
// set it in the request header - ctx.GetHeader("X-CSRF-Token", token)
|
||||||
|
// This is useful if you're sending JSON to clients or a front-end JavaScript
|
||||||
|
// framework.
|
||||||
|
}
|
||||||
|
|
||||||
|
func postSignupForm(ctx iris.Context) {
|
||||||
|
ctx.Writef("You're welcome mate!")
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<form method="POST" action="/user/signup">
|
||||||
|
{{ .csrfField }}
|
||||||
|
<button type="submit">Proceed</button>
|
||||||
|
</form>
|
46
_examples/experimental-handlers/jwt/main.go
Normal file
46
_examples/experimental-handlers/jwt/main.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// iris provides some basic middleware, most for your learning curve.
|
||||||
|
// You can use any net/http compatible middleware with iris.FromStd wrapper.
|
||||||
|
//
|
||||||
|
// JWT net/http video tutorial for golang newcomers: https://www.youtube.com/watch?v=dgJFeqeXVKw
|
||||||
|
//
|
||||||
|
// This middleware is the only one cloned from external source: https://github.com/auth0/go-jwt-middleware
|
||||||
|
// (because it used "context" to define the user but we don't need that so a simple iris.FromStd wouldn't work as expected.)
|
||||||
|
package main
|
||||||
|
|
||||||
|
// $ go get -u github.com/dgrijalva/jwt-go
|
||||||
|
// $ go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/dgrijalva/jwt-go"
|
||||||
|
jwtmiddleware "github.com/iris-contrib/middleware/jwt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func myHandler(ctx iris.Context) {
|
||||||
|
user := ctx.Values().Get("jwt").(*jwt.Token)
|
||||||
|
|
||||||
|
ctx.Writef("This is an authenticated request\n")
|
||||||
|
ctx.Writef("Claim content:\n")
|
||||||
|
|
||||||
|
ctx.Writef("%s", user.Signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
jwtHandler := jwtmiddleware.New(jwtmiddleware.Config{
|
||||||
|
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte("My Secret"), nil
|
||||||
|
},
|
||||||
|
// When set, the middleware verifies that tokens are signed with the specific signing algorithm
|
||||||
|
// If the signing method is not constant the ValidationKeyGetter callback can be used to implement additional checks
|
||||||
|
// Important to avoid security issues described here: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
|
||||||
|
SigningMethod: jwt.SigningMethodHS256,
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Use(jwtHandler.Serve)
|
||||||
|
|
||||||
|
app.Get("/ping", myHandler)
|
||||||
|
app.Run(iris.Addr("localhost:3001"))
|
||||||
|
} // don't forget to look ../jwt_test.go to see how to set your own custom claims
|
24
_examples/experimental-handlers/newrelic/simple/main.go
Normal file
24
_examples/experimental-handlers/newrelic/simple/main.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/iris-contrib/middleware/newrelic"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
config := newrelic.Config("APP_SERVER_NAME", "NEWRELIC_LICENSE_KEY")
|
||||||
|
config.Enabled = true
|
||||||
|
m, err := newrelic.New(config)
|
||||||
|
if err != nil {
|
||||||
|
app.Logger().Fatal(err)
|
||||||
|
}
|
||||||
|
app.Use(m.ServeHTTP)
|
||||||
|
|
||||||
|
app.Get("/", func(ctx iris.Context) {
|
||||||
|
ctx.Writef("success!\n")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
39
_examples/experimental-handlers/prometheus/simple/main.go
Normal file
39
_examples/experimental-handlers/prometheus/simple/main.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
prometheusMiddleware "github.com/iris-contrib/middleware/prometheus"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
m := prometheusMiddleware.New("serviceName", 0.3, 1.2, 5.0)
|
||||||
|
|
||||||
|
app.Use(m.ServeHTTP)
|
||||||
|
|
||||||
|
app.OnErrorCode(iris.StatusNotFound, func(ctx iris.Context) {
|
||||||
|
// error code handlers are not sharing the same middleware as other routes, so we have
|
||||||
|
// to call them inside their body.
|
||||||
|
m.ServeHTTP(ctx)
|
||||||
|
|
||||||
|
ctx.Writef("Not Found")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Get("/", func(ctx iris.Context) {
|
||||||
|
sleep := rand.Intn(4999) + 1
|
||||||
|
time.Sleep(time.Duration(sleep) * time.Millisecond)
|
||||||
|
ctx.Writef("Slept for %d milliseconds", sleep)
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Get("/metrics", iris.FromStd(promhttp.Handler()))
|
||||||
|
|
||||||
|
// http://localhost:8080/
|
||||||
|
// http://localhost:8080/anotfound
|
||||||
|
// http://localhost:8080/metrics
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
38
_examples/experimental-handlers/secure/simple/main.go
Normal file
38
_examples/experimental-handlers/secure/simple/main.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/iris-contrib/middleware/secure"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := secure.New(secure.Options{
|
||||||
|
AllowedHosts: []string{"ssl.example.com"}, // AllowedHosts is a list of fully qualified domain names that are allowed. Default is empty list, which allows any and all host names.
|
||||||
|
SSLRedirect: true, // If SSLRedirect is set to true, then only allow HTTPS requests. Default is false.
|
||||||
|
SSLTemporaryRedirect: false, // If SSLTemporaryRedirect is true, the a 302 will be used while redirecting. Default is false (301).
|
||||||
|
SSLHost: "ssl.example.com", // SSLHost is the host name that is used to redirect HTTP requests to HTTPS. Default is "", which indicates to use the same host.
|
||||||
|
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"}, // SSLProxyHeaders is set of header keys with associated values that would indicate a valid HTTPS request. Useful when using Nginx: `map[string]string{"X-Forwarded-Proto": "https"}`. Default is blank map.
|
||||||
|
STSSeconds: 315360000, // STSSeconds is the max-age of the Strict-Transport-Security header. Default is 0, which would NOT include the header.
|
||||||
|
STSIncludeSubdomains: true, // If STSIncludeSubdomains is set to true, the `includeSubdomains` will be appended to the Strict-Transport-Security header. Default is false.
|
||||||
|
STSPreload: true, // If STSPreload is set to true, the `preload` flag will be appended to the Strict-Transport-Security header. Default is false.
|
||||||
|
ForceSTSHeader: false, // STS header is only included when the connection is HTTPS. If you want to force it to always be added, set to true. `IsDevelopment` still overrides this. Default is false.
|
||||||
|
FrameDeny: true, // If FrameDeny is set to true, adds the X-Frame-Options header with the value of `DENY`. Default is false.
|
||||||
|
CustomFrameOptionsValue: "SAMEORIGIN", // CustomFrameOptionsValue allows the X-Frame-Options header value to be set with a custom value. This overrides the FrameDeny option.
|
||||||
|
ContentTypeNosniff: true, // If ContentTypeNosniff is true, adds the X-Content-Type-Options header with the value `nosniff`. Default is false.
|
||||||
|
BrowserXSSFilter: true, // If BrowserXssFilter is true, adds the X-XSS-Protection header with the value `1; mode=block`. Default is false.
|
||||||
|
ContentSecurityPolicy: "default-src 'self'", // ContentSecurityPolicy allows the Content-Security-Policy header value to be set with a custom value. Default is "".
|
||||||
|
PublicKey: `pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubdomains; report-uri="https://www.example.com/hpkp-report"`, // PublicKey implements HPKP to prevent MITM attacks with forged certificates. Default is "".
|
||||||
|
|
||||||
|
IsDevelopment: true, // This will cause the AllowedHosts, SSLRedirect, and STSSeconds/STSIncludeSubdomains options to be ignored during development. When deploying to production, be sure to set this to false.
|
||||||
|
})
|
||||||
|
|
||||||
|
app := iris.New()
|
||||||
|
app.Use(s.Serve)
|
||||||
|
|
||||||
|
app.Get("/home", func(ctx iris.Context) {
|
||||||
|
ctx.Writef("Hello from /home")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
|
||||||
|
"github.com/didip/tollbooth"
|
||||||
|
"github.com/iris-contrib/middleware/tollboothic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// $ go get github.com/didip/tollbooth
|
||||||
|
// $ go run main.go
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
limiter := tollbooth.NewLimiter(1, nil)
|
||||||
|
//
|
||||||
|
// or create a limiter with expirable token buckets
|
||||||
|
// This setting means:
|
||||||
|
// create a 1 request/second limiter and
|
||||||
|
// every token bucket in it will expire 1 hour after it was initially set.
|
||||||
|
// limiter := tollbooth.NewLimiter(1, &limiter.ExpirableOptions{DefaultExpirationTTL: time.Hour})
|
||||||
|
|
||||||
|
app.Get("/", tollboothic.LimitHandler(limiter), func(ctx iris.Context) {
|
||||||
|
ctx.HTML("<b>Hello, world!</b>")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read more at: https://github.com/didip/tollbooth
|
|
@ -4,5 +4,9 @@ package httptest
|
||||||
|
|
||||||
import "github.com/gavv/httpexpect"
|
import "github.com/gavv/httpexpect"
|
||||||
|
|
||||||
// Request type alias.
|
type (
|
||||||
type Request = httpexpect.Request
|
// Request type alias.
|
||||||
|
Request = httpexpect.Request
|
||||||
|
// Expect type alias.
|
||||||
|
Expect = httpexpect.Expect
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user