Skip to content

Commit 19c6592

Browse files
committed
Add en/0.6.x.md syntax highlighting
1 parent 919364c commit 19c6592

File tree

4 files changed

+45
-45
lines changed

4 files changed

+45
-45
lines changed

en/06.1.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ If your application does set an expiry time (for example, setMaxAge(60*60*24)),
3535
## Set cookies in Go
3636

3737
Go uses the `SetCookie` function in the `net/http` package to set cookies:
38-
38+
```Go
3939
http.SetCookie(w ResponseWriter, cookie *Cookie)
40-
40+
```
4141
`w` is the response of the request and cookie is a struct. Let's see what it looks like:
42-
42+
```Go
4343
type Cookie struct {
4444
Name string
4545
Value string
@@ -57,27 +57,27 @@ Go uses the `SetCookie` function in the `net/http` package to set cookies:
5757
Raw string
5858
Unparsed []string // Raw text of unparsed attribute-value pairs
5959
}
60-
60+
```
6161
Here is an example of setting a cookie:
62-
62+
```Go
6363
expiration := time.Now().Add(365 * 24 * time.Hour)
6464
cookie := http.Cookie{Name: "username", Value: "astaxie", Expires: expiration}
6565
http.SetCookie(w, &cookie)
66-
  
66+
```  
6767
6868
## Fetch cookies in Go
6969
7070
The above example shows how to set a cookie. Now let's see how to get a cookie that has been set:
71-
71+
```Go
7272
cookie, _ := r.Cookie("username")
7373
fmt.Fprint(w, cookie)
74-
74+
```
7575
Here is another way to get a cookie:
76-
76+
```Go
7777
for _, cookie := range r.Cookies() {
7878
fmt.Fprint(w, cookie.Name)
7979
}
80-
80+
```
8181
As you can see, it's very convenient to get cookies from requests.
8282

8383
## Sessions

en/06.2.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Next, we'll examine a complete example of a Go session manager and the rationale
3434
### Session manager
3535

3636
Define a global session manager:
37-
37+
```Go
3838
type Manager struct {
3939
cookieName string //private cookiename
4040
lock sync.Mutex // protects session
@@ -49,40 +49,40 @@ Define a global session manager:
4949
}
5050
return &Manager{provider: provider, cookieName: cookieName, maxlifetime: maxlifetime}, nil
5151
}
52-
52+
```
5353
Create a global session manager in the `main()` function:
54-
54+
```Go
5555
var globalSessions *session.Manager
5656
// Then, initialize the session manager
5757
func init() {
5858
globalSessions = NewManager("memory","gosessionid",3600)
5959
}
60-
60+
```
6161
We know that we can save sessions in many ways including in memory, the file system or directly into the database. We need to define a `Provider` interface in order to represent the underlying structure of our session manager:
62-
62+
```Go
6363
type Provider interface {
6464
SessionInit(sid string) (Session, error)
6565
SessionRead(sid string) (Session, error)
6666
SessionDestroy(sid string) error
6767
SessionGC(maxLifeTime int64)
6868
}
69-
69+
```
7070
- `SessionInit` implements the initialization of a session, and returns a new session if it succeeds.
7171
- `SessionRead` returns a session represented by the corresponding sid. Creates a new session and returns it if it does not already exist.
7272
- `SessionDestroy` given an sid, deletes the corresponding session.
7373
- `SessionGC` deletes expired session variables according to `maxLifeTime`.
7474

7575
So what methods should our session interface have? If you have any experience in web development, you should know that there are only four operations for sessions: set value, get value, delete value and get current session id. So, our session interface should have four methods to perform these operations.
76-
76+
```Go
7777
type Session interface {
7878
Set(key, value interface{}) error //set session value
7979
Get(key interface{}) interface{} //get session value
8080
Delete(key interface{}) error //delete session value
8181
SessionID() string //back current sessionID
8282
}
83-
83+
```
8484
This design takes its roots from the `database/sql/driver`, which defines the interface first, then registers specific structures when we want to use it. The following code is the internal implementation of a session register function.
85-
85+
```Go
8686
var provides = make(map[string]Provider)
8787

8888
// Register makes a session provider available by the provided name.
@@ -97,23 +97,23 @@ This design takes its roots from the `database/sql/driver`, which defines the in
9797
}
9898
provides[name] = provider
9999
}
100-
100+
```
101101
### Unique session id's
102102

103103
Session id's are for identifying users of web applications, so they must be unique. The following code shows how to achieve this goal:
104-
104+
```Go
105105
func (manager *Manager) sessionId() string {
106106
b := make([]byte, 32)
107107
if _, err := io.ReadFull(rand.Reader, b); err != nil {
108108
return ""
109109
}
110110
return base64.URLEncoding.EncodeToString(b)
111111
}
112-
112+
```
113113
### Creating a session
114114

115115
We need to allocate or get an existing session in order to validate user operations. The `SessionStart` function is for checking the existence of any sessions related to the current user, and creating a new session if none is found.
116-
116+
```Go
117117
func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session Session) {
118118
manager.lock.Lock()
119119
defer manager.lock.Unlock()
@@ -129,9 +129,9 @@ We need to allocate or get an existing session in order to validate user operati
129129
}
130130
return
131131
}
132-
132+
```
133133
Here is an example that uses sessions for a login operation.
134-
134+
```Go
135135
func login(w http.ResponseWriter, r *http.Request) {
136136
sess := globalSessions.SessionStart(w, r)
137137
r.ParseForm()
@@ -144,13 +144,13 @@ Here is an example that uses sessions for a login operation.
144144
http.Redirect(w, r, "/", 302)
145145
}
146146
}
147-
147+
```
148148
### Operation value: set, get and delete
149149

150150
The `SessionStart` function returns a variable that implements a session interface. How do we use it?
151151

152152
You saw `session.Get("uid")` in the above example for a basic operation. Now let's examine a more detailed example.
153-
153+
```Go
154154
func count(w http.ResponseWriter, r *http.Request) {
155155
sess := globalSessions.SessionStart(w, r)
156156
createtime := sess.Get("createtime")
@@ -170,16 +170,16 @@ You saw `session.Get("uid")` in the above example for a basic operation. Now let
170170
w.Header().Set("Content-Type", "text/html")
171171
t.Execute(w, sess.Get("countnum"))
172172
}
173-
173+
```
174174
As you can see, operating on sessions simply involves using the key/value pattern in the Set, Get and Delete operations.
175175

176176
Because sessions have the concept of an expiry time, we define the GC to update the session's latest modify time. This way, the GC will not delete sessions that have expired but are still being used.
177177

178178
### Reset sessions
179179

180180
We know that web applications have a logout operation. When users logout, we need to delete the corresponding session. We've already used the reset operation in above example -now let's take a look at the function body.
181-
182-
//Destroy sessionid
181+
```Go
182+
// Destroy sessionid
183183
func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request){
184184
cookie, err := r.Cookie(manager.cookieName)
185185
if err != nil || cookie.Value == "" {
@@ -193,11 +193,11 @@ We know that web applications have a logout operation. When users logout, we nee
193193
http.SetCookie(w, &cookie)
194194
}
195195
}
196-
196+
```
197197
### Delete sessions
198198

199199
Let's see how to let the session manager delete a session. We need to start the GC in the `main()` function:
200-
200+
```Go
201201
func init() {
202202
go globalSessions.GC()
203203
}
@@ -208,7 +208,7 @@ Let's see how to let the session manager delete a session. We need to start the
208208
manager.provider.SessionGC(manager.maxlifetime)
209209
time.AfterFunc(time.Duration(manager.maxlifetime), func() { manager.GC() })
210210
}
211-
211+
```
212212
We see that the GC makes full use of the timer function in the `time` package. It automatically calls GC when the session times out, ensuring that all sessions are usable during `maxLifeTime`. A similar solution can be used to count online users.
213213

214214
## Summary

en/06.3.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# 6.3 Session storage
22

33
We introduced a simple session manager's working principles in the previous section, and among other things, we defined a session storage interface. In this section, I'm going to show you an example of a memory based session storage engine that implements this interface. You can tailor this to other forms of session storage as well.
4-
4+
```Go
55
package memory
66

77
import (
@@ -114,24 +114,24 @@ We introduced a simple session manager's working principles in the previous sect
114114
session.Register("memory", pder)
115115
}
116116

117-
117+
```
118118
The above example implements a memory based session storage mechanism. It uses its `init()` function to register this storage engine to the session manager. So how do we register this engine from our main program?
119-
119+
```Go
120120
import (
121121
"github.com/astaxie/session"
122122
_ "github.com/astaxie/session/providers/memory"
123123
)
124-
124+
```
125125
We use the blank import mechanism (which will invoke the package's `init()` function automatically) to register this engine to a session manager. We then use the following code to initialize the session manager:
126-
126+
```Go
127127
var globalSessions *session.Manager
128128

129129
// initialize in init() function
130130
func init() {
131131
globalSessions, _ = session.NewManager("memory", "gosessionid", 3600)
132132
go globalSessions.GC()
133133
}
134-
134+
```
135135
## Links
136136

137137
- [Directory](preface.md)

en/06.4.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ In this section, we are going to show you how to hijack a session for educationa
77
## The session hijacking process
88

99
The following code is a counter for the `count` variable:
10-
10+
```Go
1111
func count(w http.ResponseWriter, r *http.Request) {
1212
sess := globalSessions.SessionStart(w, r)
1313
ct := sess.Get("countnum")
@@ -20,7 +20,7 @@ The following code is a counter for the `count` variable:
2020
w.Header().Set("Content-Type", "text/html")
2121
t.Execute(w, sess.Get("countnum"))
2222
}
23-
23+
```
2424
The content of `count.gtpl` is as follows:
2525

2626
Hi. Now count:{{.}}
@@ -60,7 +60,7 @@ Through this simple example of hijacking a session, you can see that it's very d
6060
The first step is to only set session id's in cookies, instead of in URL rewrites. Also, we should set the httponly cookie property to true. This restricts client-side scripts from gaining access to the session id. Using these techniques, cookies cannot be accessed by XSS and it won't be as easy as we demonstrated to get a session id from a cookie manager.
6161

6262
The second step is to add a token to every request. Similar to the manner in which we dealt with repeating form submissions in previous sections, we add a hidden field that contains a token. When a request is sent to the server, we can verify this token to prove that the request is unique.
63-
63+
```Go
6464
h := md5.New()
6565
salt:="astaxie%^7&8888"
6666
io.WriteString(h,salt+time.Now().String())
@@ -69,19 +69,19 @@ The second step is to add a token to every request. Similar to the manner in whi
6969
// ask to log in
7070
}
7171
sess.Set("token",token)
72-
72+
```
7373
### Session id timeout
7474

7575
Another solution is to add a create time for every session, and to replace expired session id's with new ones. This can prevent session hijacking under certain circumstances such as when the hijack is attempted too late.
76-
76+
```Go
7777
createtime := sess.Get("createtime")
7878
if createtime == nil {
7979
sess.Set("createtime", time.Now().Unix())
8080
} else if (createtime.(int64) + 60) < (time.Now().Unix()) {
8181
globalSessions.SessionDestroy(w, r)
8282
sess = globalSessions.SessionStart(w, r)
8383
}
84-
84+
```
8585
We set a value to save the create time and check if it's expired (I set 60 seconds here). This step can often thwart session hijacking attempts.
8686

8787
By combining the two solutions set out above you will be able to prevent most session hijacking attempts from succeeding. On the one hand, session id's that are frequently reset will result in an attacker always getting expired and useless session id's; on the other hand, by setting the httponly property on cookies and ensuring that session id's can only be passed via cookies, all URL based attacks are mitigated. Finally, we set `MaxAge=0` on our cookies, which means that the session id's will not be saved in the browser history.

0 commit comments

Comments
 (0)