Golang Web 的小技巧(持續更新)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

1. 避免注入(轉義)

name := url.QueryEscape(user.Name)

2. 使用 middleware 對每個請求做處理,使用 session中介層 對一類請求作處理。

中介層原理

中介層依靠 context 傳遞變數。一個請求的 context不僅僅綁定了 request和 response,還綁定了 handlers HandlersChain。所以用戶端的每個請求都會經過 middleware處理。

原理很簡單:由上可知 middleware 會對每個請求作處理。我們在中介層中定義一個 session 對象。這樣,每個請求的 context 都會儲存一個 session對象。session對象通過判斷 sessionId是否存在來判斷是否是同一個 session 對象。如果是同一個 session,那麼就可以從 session中擷取相應的值。

session 的實現機制

服務端產生一個 sessionId 儲存到 cookie中。當然還可以將 session中的所有內容儲存到 cookie中。討論前者,有了 sessionId,每次請求時會攜帶這個 sessionId的 cookie。這樣服務端就可以判斷 sessionId 是否存在來擷取相應的的 session。

3. 封裝 websocket

type connection struct {ws *websocket.Conn// send chan []byteuser *Userroom *Room}

4. 建立 config 包

package mainimport ("net/url""os""reflect")type RedisConfig struct {Host     string `default:"redis://localhost:6379"`Password string `default:""`}type ServerConfig struct {Port   string `default:"3000"`Secret string `default:"secret"`}type Config struct {Redis  RedisConfigServer ServerConfig}// Session expiration (from github.com/boj/redistore)const sessionExpire = 86400 * 30var CONFIG = confApp()func confApp() Config {_redis := confRedis(os.Getenv("REDIS_URL"))_server := confServer(os.Getenv("PORT"))return Config{Redis:  _redis,Server: _server,}}func confRedis(connUrl string) RedisConfig {_redis := RedisConfig{}typ := reflect.TypeOf(_redis)if connUrl == "" {h, _ := typ.FieldByName("Host")_redis.Host = h.Tag.Get("default")p, _ := typ.FieldByName("Password")_redis.Password = p.Tag.Get("default")return _redis}redisURL, err := url.Parse(connUrl)if err != nil {panic(err)}auth := ""if redisURL.User != nil {if password, ok := redisURL.User.Password(); ok {auth = password}}return RedisConfig{Host:     redisURL.Host,Password: auth,}}func confServer(port string) ServerConfig {_conf := ServerConfig{Secret: "learngo",}typ := reflect.TypeOf(_conf)if port == "" {p, _ := typ.FieldByName("Port")_conf.Port = p.Tag.Get("default")return _conf}_conf.Port = portreturn _conf}

5. 封裝 db的 close方法到中介層

db 初始化封裝到 init 函數中

func init() {db.Connect()}

通過中介層,將 db儲存到 context中

// Connect middleware clones the database session for each request and// makes the `db` object available for each handlerfunc Connect(c *gin.Context) {s := db.Session.Clone()defer s.Close()c.Set("db", s.DB(db.Mongo.Database))c.Next()}

6. 對 action進行日誌封裝到 log檔案

type Log struct {PlayerName string `json:"playername"`Action     string `json:"action"`TakeCard   Card   `json:"takecard"`PutCards   []Card `json:"putcards"`Option     string `json:"option"`}func (a *Action) ToLog(g *Game) {PutCards := make([]Card, 0)TakeCard := g.CardFromReference(a.TakeCard)for _, id := range a.PutCards {PutCards = append(PutCards, g.CardFromReference(id))}g.LastLog = &Log{a.PlayerName, a.Name, TakeCard, PutCards, a.Option}}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.