码迷,mamicode.com
首页 > 其他好文 > 详细

Golang的session管理器

时间:2016-07-14 13:15:50      阅读:784      评论:0      收藏:0      [点我收藏+]

标签:

对于一些需要对用户进行管理(比如验证操作的权限等)的站点来说,session管理器是必不可少的。下面实现了一个线程安全的简单session管理类。
生产环境:golang1.4.2+win7x64
golang1.4.2+centos6.5×64

1.代码如下:

  1 package Helper  
  2   
  3 import (  
  4     “crypto/rand”  
  5     “encoding/base64″  
  6     “io”  
  7     “net/http”  
  8     “net/url”  
  9     “strconv”  
 10     “sync”  
 11     “time”  
 12 )  
 13   
 14 /*Session会话管理*/  
 15 type SessionMgr struct {  
 16     mCookieName  string       //客户端cookie名称  
 17     mLock        sync.RWMutex //互斥(保证线程安全)  
 18     mMaxLifeTime int64        //垃圾回收时间  
 19   
 20     mSessions map[string]*Session //保存session的指针[sessionID] = session  
 21 }  
 22   
 23 //创建会话管理器(cookieName:在浏览器中cookie的名字;maxLifeTime:最长生命周期)  
 24 func NewSessionMgr(cookieName string, maxLifeTime int64) *SessionMgr {  
 25     mgr := &SessionMgr{mCookieName: cookieName, mMaxLifeTime: maxLifeTime, mSessions: make(map[string]*Session)}  
 26   
 27     //启动定时回收  
 28     go mgr.GC()  
 29   
 30     return mgr  
 31 }  
 32   
 33 //在开始页面登陆页面,开始Session  
 34 func (mgr *SessionMgr) StartSession(w http.ResponseWriter, r *http.Request) string {  
 35     mgr.mLock.Lock()  
 36     defer mgr.mLock.Unlock()  
 37   
 38     //无论原来有没有,都重新创建一个新的session  
 39     newSessionID := url.QueryEscape(mgr.NewSessionID())  
 40   
 41     //存指针  
 42     var session *Session = &Session{mSessionID: newSessionID, mLastTimeAccessed: time.Now(), mValues: make(map[interface{}]interface{})}  
 43     mgr.mSessions[newSessionID] = session  
 44     //让浏览器cookie设置过期时间  
 45     cookie := http.Cookie{Name: mgr.mCookieName, Value: newSessionID, Path: “/”, HttpOnly: true, MaxAge: int(mgr.mMaxLifeTime)}  
 46     http.SetCookie(w, &cookie)  
 47   
 48     return newSessionID  
 49 }  
 50   
 51 //结束Session  
 52 func (mgr *SessionMgr) EndSession(w http.ResponseWriter, r *http.Request) {  
 53     cookie, err := r.Cookie(mgr.mCookieName)  
 54     if err != nil || cookie.Value == “” {  
 55         return  
 56     } else {  
 57         mgr.mLock.Lock()  
 58         defer mgr.mLock.Unlock()  
 59   
 60         delete(mgr.mSessions, cookie.Value)  
 61   
 62         //让浏览器cookie立刻过期  
 63         expiration := time.Now()  
 64         cookie := http.Cookie{Name: mgr.mCookieName, Path: “/”, HttpOnly: true, Expires: expiration, MaxAge: -1}  
 65         http.SetCookie(w, &cookie)  
 66     }  
 67 }  
 68   
 69 //结束session  
 70 func (mgr *SessionMgr) EndSessionBy(sessionID string) {  
 71     mgr.mLock.Lock()  
 72     defer mgr.mLock.Unlock()  
 73   
 74     delete(mgr.mSessions, sessionID)  
 75 }  
 76   
 77 //设置session里面的值  
 78 func (mgr *SessionMgr) SetSessionVal(sessionID string, key interface{}, value interface{}) {  
 79     mgr.mLock.Lock()  
 80     defer mgr.mLock.Unlock()  
 81   
 82     if session, ok := mgr.mSessions[sessionID]; ok {  
 83         session.mValues[key] = value  
 84     }  
 85 }  
 86   
 87 //得到session里面的值  
 88 func (mgr *SessionMgr) GetSessionVal(sessionID string, key interface{}) (interface{}, bool) {  
 89     mgr.mLock.RLock()  
 90     defer mgr.mLock.RUnlock()  
 91   
 92     if session, ok := mgr.mSessions[sessionID]; ok {  
 93         if val, ok := session.mValues[key]; ok {  
 94             return val, ok  
 95         }  
 96     }  
 97   
 98     return nil, false  
 99 }  
100   
101 //得到sessionID列表  
102 func (mgr *SessionMgr) GetSessionIDList() []string {  
103     mgr.mLock.RLock()  
104     defer mgr.mLock.RUnlock()  
105   
106     sessionIDList := make([]string, 0)  
107   
108     for k, _ := range mgr.mSessions {  
109         sessionIDList = append(sessionIDList, k)  
110     }  
111   
112     return sessionIDList[0:len(sessionIDList)]  
113 }  
114   
115 //判断Cookie的合法性(每进入一个页面都需要判断合法性)  
116 func (mgr *SessionMgr) CheckCookieValid(w http.ResponseWriter, r *http.Request) string {  
117     var cookie, err = r.Cookie(mgr.mCookieName)  
118   
119     if cookie == nil ||  
120         err != nil {  
121         return “”  
122     }  
123   
124     mgr.mLock.Lock()  
125     defer mgr.mLock.Unlock()  
126   
127     sessionID := cookie.Value  
128   
129     if session, ok := mgr.mSessions[sessionID]; ok {  
130         session.mLastTimeAccessed = time.Now() //判断合法性的同时,更新最后的访问时间  
131         return sessionID  
132     }  
133   
134     return “”  
135 }  
136   
137 //更新最后访问时间  
138 func (mgr *SessionMgr) GetLastAccessTime(sessionID string) time.Time {  
139     mgr.mLock.RLock()  
140     defer mgr.mLock.RUnlock()  
141   
142     if session, ok := mgr.mSessions[sessionID]; ok {  
143         return session.mLastTimeAccessed  
144     }  
145   
146     return time.Now()  
147 }  
148   
149 //GC回收  
150 func (mgr *SessionMgr) GC() {  
151     mgr.mLock.Lock()  
152     defer mgr.mLock.Unlock()  
153   
154     for sessionID, session := range mgr.mSessions {  
155         //删除超过时限的session  
156         if session.mLastTimeAccessed.Unix()+mgr.mMaxLifeTime < time.Now().Unix() {  
157             delete(mgr.mSessions, sessionID)  
158         }  
159     }  
160   
161     //定时回收  
162     time.AfterFunc(time.Duration(mgr.mMaxLifeTime)*time.Second, func() { mgr.GC() })  
163 }  
164   
165 //创建唯一ID  
166 func (mgr *SessionMgr) NewSessionID() string {  
167     b := make([]byte, 32)  
168     if _, err := io.ReadFull(rand.Reader, b); err != nil {  
169         nano := time.Now().UnixNano() //微秒  
170         return strconv.FormatInt(nano, 10)  
171     }  
172     return base64.URLEncoding.EncodeToString(b)  
173 }  
174   
175 //——————————————————————————  
176 /*会话*/  
177 type Session struct {  
178     mSessionID        string                      //唯一id  
179     mLastTimeAccessed time.Time                   //最后访问时间  
180     mValues           map[interface{}]interface{} //其它对应值(保存用户所对应的一些值,比如用户权限之类)  
181 }

 

2.使用方法
①定义一个全局变量

1 var sessionMgr *Helper.SessionMgr = nil //session管理器

 

②在程序入口处,创建一个session的对象

1 //创建session管理器,”TestCookieName”是浏览器中cookie的名字,3600是浏览器cookie的有效时间(秒)  
2 sessionMgr = Helper.NewSessionMgr(“TestCookieName”, 3600)

 

③在用户登录时进行登录用户合法性判断并设置属性

 1 //处理登录  
 2 func login(w http.ResponseWriter, r *http.Request) {  
 3     if r.Method == “GET” {  
 4         t, _ := template.ParseFiles(“web/MgrSvr_login.html”)  
 5         t.Execute(w, nil)  
 6   
 7     } else if r.Method == “POST” {  
 8         //请求的是登陆数据,那么执行登陆的逻辑判断  
 9         r.ParseForm()  
10   
11         //可以使用template.HTMLEscapeString()来避免用户进行js注入  
12         username := r.FormValue(“username”)  
13         password := r.FormValue(“password”)  
14   
15         //在数据库中得到对应数据  
16         var userID int = 0  
17   
18         userRow := db.QueryRow(loginUserQuery, username, password)  
19         userRow.Scan(&userID)  
20   
21         //TODO:判断用户名和密码  
22         if userID != 0 {  
23             //创建客户端对应cookie以及在服务器中进行记录  
24             var sessionID = sessionMgr.StartSession(w, r)  
25   
26             var loginUserInfo = UserInfo{ID: userID, UserName: username, Password: password, Alias: alias,  
27                 Desc: desc, ChannelAuth: channel_authority, IsSuperAdmin: is_super_admin, IsNewClientAuth: is_newclient_authority,  
28                 IsPayAuth: is_pay_authority, IsItemsAuth: is_itmes_authority, IsRealtimeAuth: is_realtime_authority,  
29                 IsPayCodeAuth: is_paycode_authority, IsUserAuth: is_user_authority, IsBgOpAuth: is_bgop_authority, IsHZRaidenNMMWeak: is_hz_raidenn_mmweak,  
30                 IsManualDataMgr: is_manual_data_mgr, IsManualDataQuery: is_manual_data_query}  
31   
32             //踢除重复登录的  
33             var onlineSessionIDList = sessionMgr.GetSessionIDList()  
34   
35             for _, onlineSessionID := range onlineSessionIDList {  
36                 if userInfo, ok := sessionMgr.GetSessionVal(onlineSessionID, “UserInfo”); ok {  
37                     if value, ok := userInfo.(UserInfo); ok {  
38                         if value.ID == userID {  
39                             sessionMgr.EndSessionBy(onlineSessionID)  
40                         }  
41                     }  
42                 }  
43             }  
44   
45             //设置变量值  
46             sessionMgr.SetSessionVal(sessionID, “UserInfo”, loginUserInfo)  
47   
48             //TODO 设置其它数据  
49   
50             //TODO 转向成功页面  
51   
52             return  
53         }  
54     }  
55 }

 

③在用户退出时删除对应session

1 //处理退出  
2 func logout(w http.ResponseWriter, r *http.Request) {  
3     sessionMgr.EndSession(w, r) //用户退出时删除对应session  
4     http.Redirect(w, r, “/login”, http.StatusFound)  
5     return  
6 }

 

④在每个页面中进行用户合法性验证

1 func test_session_valid(w http.ResponseWriter, r *http.Request) {  
2     var sessionID = sessionMgr.CheckCookieValid(w, r)  
3   
4     if sessionID == “” {  
5         http.Redirect(w, r, “/login”, http.StatusFound)  
6         return  
7     }  
8 }

 

Golang的session管理器

标签:

原文地址:http://www.cnblogs.com/chevin/p/5669940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!