博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang Web 的小技巧(持续更新)
阅读量:5872 次
发布时间:2019-06-19

本文共 2880 字,大约阅读时间需要 9 分钟。

  hot3.png

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 []byte	user *User	room *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  RedisConfig	Server 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 = port	return _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}}

 

转载于:https://my.oschina.net/lemos/blog/1438803

你可能感兴趣的文章
Rust 1.34.1 稳定版发布,Bug 修复
查看>>
第十一章:可绑定的基础结构(四)
查看>>
最全Handler解读,持续补充...
查看>>
[LeetCode]119.Pascal's Triangle II
查看>>
为了更准确的验证码而奋斗-云大urp教务系统大作战(1.5)
查看>>
JDBC之代码优化
查看>>
慕课网-C++远征之多态篇(中)-学习笔记
查看>>
EOS Keosd概述
查看>>
Hibernate Search 6.0.0.Alpha3 发布,数据检索框架
查看>>
DiQuick Web UI 框架 V1.3.2 版本更新
查看>>
python3入门与实践
查看>>
Tomcat7.0源码分析——server.xml文件的加载与解析
查看>>
React 16 之 测试单元(Jest+React+Enzyme)
查看>>
Leetcode打卡 | No.24 两两交换链表中的节点
查看>>
Hive过滤脏数据的一些经验
查看>>
Redis5.0重量级特性Stream尝鲜
查看>>
阿里云的技术创新,不是简单的路线之争
查看>>
引入css外部样式表的注意事项
查看>>
Apache Drill学习
查看>>
Rust 创始人谈 Rust 2019 和未来:社区应限制成长速度
查看>>