-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
main.go
121 lines (103 loc) · 3.69 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Package main shows how to use a dependency to check if a user is logged in
// using a special custom Go type `Authenticated`, which when,
// present on a controller's method or a field then
// it limits the visibility to "authenticated" users only.
//
// The same result could be done through a middleware as well, however using a static type
// any person reads your code can see that an "X" controller or method
// should only be used by "authenticated" users.
package main
import (
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/mvc"
"github.com/kataras/iris/v12/sessions"
)
func main() {
app := newApp()
// app.UseRouter(iris.Compression)
app.Logger().SetLevel("debug")
// Open a client, e.g. Postman and visit the below endpoints.
// GET: http://localhost:8080/user (UnauthenticatedUserController.Get)
// POST: http://localhost:8080/user/login (UnauthenticatedUserController.PostLogin)
// GET: http://localhost:8080/user (UserController.Get)
// POST: http://localhost:8080/user/logout (UserController.PostLogout)
app.Listen(":8080")
}
func newApp() *iris.Application {
app := iris.New()
sess := sessions.New(sessions.Config{
Cookie: "myapp_session_id",
AllowReclaim: true,
})
app.Use(sess.Handler())
userRouter := app.Party("/user")
{
// Use that in order to be able to register a route twice,
// last one will be executed if the previous route's handler(s) stopped and the response can be reset-ed.
// See core/router/route_register_rule_test.go#TestRegisterRuleOverlap.
userRouter.SetRegisterRule(iris.RouteOverlap)
// Initialize a new MVC application on top of the "userRouter".
userApp := mvc.New(userRouter)
// Register Dependencies.
userApp.Register(authDependency)
// Register Controllers.
userApp.Handle(new(UserController))
userApp.Handle(new(UnauthenticatedUserController))
}
return app
}
// Authenticated is a custom type used as "annotation" for resources that requires authentication,
// its value should be the logged user ID.
type Authenticated uint64
func authDependency(ctx iris.Context, session *sessions.Session) Authenticated {
userID := session.GetUint64Default("user_id", 0)
if userID == 0 {
// If execution was stopped
// any controller's method will not be executed at all.
//
// Note that, the below will not fire the error to the user:
// ctx.StopWithStatus(iris.StatusUnauthorized)
// because of the imaginary:
// UnauthenticatedUserController.Get() (string, int) {
// return "...", iris.StatusOK
// }
//
// OR
// If you don't want to set a status code at all:
ctx.StopExecution()
return 0
}
return Authenticated(userID)
}
// UnauthenticatedUserController serves the "public" Unauthorized User API.
type UnauthenticatedUserController struct{}
// Get registers a route that will be executed when authentication is not passed
// (see UserController.Get) too.
func (c *UnauthenticatedUserController) Get() string {
return "custom action to redirect on authentication page"
}
// PostLogin serves
// POST: /user/login
func (c *UnauthenticatedUserController) PostLogin(session *sessions.Session) mvc.Response {
session.Set("user_id", 1)
// Redirect (you can still use the Context.Redirect if you want so).
return mvc.Response{
Path: "/user",
Code: iris.StatusFound,
}
}
// UserController serves the "public" User API.
type UserController struct {
CurrentUserID Authenticated
}
// Get returns a message for the sake of the example.
// GET: /user
func (c *UserController) Get() string {
return `UserController.Get: The Authenticated type
can be used to secure a controller's method too.`
}
// PostLogout serves
// POST: /user/logout
func (c *UserController) PostLogout(ctx iris.Context) {
sessions.Get(ctx).Man.Destroy(ctx)
}