4

用go封装一下封禁功能 - 秋玻

 1 year ago
source link: https://www.cnblogs.com/weloe/p/17431331.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

用go封装一下封禁功能

本篇为用go设计开发一个自己的轻量级登录库/框架吧 - 秋玻 - 博客园 (cnblogs.com)的封禁业务篇,会讲讲封禁业务的实现,给库/框架增加新的功能。

源码:https://github.com/weloe/token-go

思路

封禁业务也是在一般项目中比较常见的业务。我们也将它封装在库中作为功能之一。

我们同样使用adapter作为底层的存储结构,将封禁标示作为k-v结构存储。

把id和服务名称service作为key,把封禁的级别level作为value,以此我们能实现一些比较常见的封禁业务。

实现

首先就是封禁方法,首先当然要校验一下参数,然后存储封禁标识。要注意的就是level要大于等于1,在封禁后也要调用我们的logger和watcher。

https://github.com/weloe/token-go/blob/8bf577c0309332cb42d17e33b435f06fb74d8e7b/enforcer.go#L390



// Banned ban user, if time == 0,the timeout is not set func (e *Enforcer) Banned(id string, service string, level int, time int64) error { if id == "" || service == "" { return fmt.Errorf("parameter cannot be nil") } if level < 1 { return fmt.Errorf("unexpected level = %v, level must large or equal 1", level) } err := e.adapter.SetStr(e.spliceBannedKey(id, service), strconv.Itoa(level), time) if err != nil { return err }

// callback e.logger.Ban(e.loginType, id, service, level, time) if e.watcher != nil { e.watcher.Ban(e.loginType, id, service, level, time) }

return nil }

再来就是解除封禁的实现,很简单,只要删除我们封禁存的那条记录就可以了。

https://github.com/weloe/token-go/blob/8bf577c0309332cb42d17e33b435f06fb74d8e7b/enforcer.go#LL412C6-L412C6



// UnBanned Unblock user account func (e *Enforcer) UnBanned(id string, services ...string) error { if id == "" { return fmt.Errorf("parmeter id can not be nil") } if len(services) == 0 { return fmt.Errorf("parmeter services length can not be 0") }

for _, service := range services { err := e.adapter.DeleteStr(e.spliceBannedKey(id, service)) if err != nil { return err } e.logger.UnBan(e.loginType, id, service) if e.watcher != nil { e.watcher.UnBan(e.loginType, id, service) } } return nil }

接着还需要提供几个方便使用的方法

分别用来判断是否被封禁,获得封禁的级别,获得封禁的剩余时间三个方法

https://github.com/weloe/token-go/blob/8bf577c0309332cb42d17e33b435f06fb74d8e7b/enforcer.go#L434

判断是否被封禁



// IsBanned if banned return true, else return false func (e *Enforcer) IsBanned(id string, services string) bool { s := e.adapter.GetStr(e.spliceBannedKey(id, services))

return s != "" }

https://github.com/weloe/token-go/blob/8bf577c0309332cb42d17e33b435f06fb74d8e7b/enforcer.go#L441

获得封禁的级别



// GetBannedLevel get banned level func (e *Enforcer) GetBannedLevel(id string, service string) (int64, error) { str := e.adapter.GetStr(e.spliceBannedKey(id, service)) if str == "" { return 0, fmt.Errorf("loginId = %v, service = %v is not banned", id, service) } time, err := strconv.ParseInt(str, 10, 64) if err != nil { return 0, err } return time, nil }

https://github.com/weloe/token-go/blob/8bf577c0309332cb42d17e33b435f06fb74d8e7b/enforcer.go#L454

获得封禁的剩余时间



// GetBannedTime get banned time func (e *Enforcer) GetBannedTime(id string, service string) int64 { timeout := e.adapter.GetStrTimeout(e.spliceBannedKey(id, service)) return timeout }

有了这几个方法,我们就可以使用token-go更为方便是实现登录业务了。

对于一般的业务,我们其实可以无视封禁级别。只需要使用Banned()进行封禁,在每个需要校验是否被封禁的业务前进行IsBanned()的判断就行了。

测试例子:



func TestEnforcer_Banned(t *testing.T) { err, enforcer, _ := NewTestEnforcer(t) if err != nil { t.Fatalf("NewTestEnforcer() failed: %v", err) } err = enforcer.Banned("1", "comment", 1, 100) if err != nil { t.Fatalf("Banned() failed: %v", err) } isBanned := enforcer.IsBanned("1", "comment") if !isBanned { t.Errorf("unexpected isBanned is false") }

err = enforcer.UnBanned("1", "comment") if err != nil { t.Fatalf("UnBanned() failed: %v", err) } isBanned = enforcer.IsBanned("1", "comment") if isBanned { t.Errorf("unexpected isBanned is false") } }

当然我们对于一个业务会有一些较为复杂的封禁,比如discuss交流业务,如果级别为1我们会禁止评论,如果级别为2我们会禁止评论和点赞,级别为3我们会禁止评论、点赞和收藏。

这个时候我们只需要再加上GetBannedLevel(),在每个业务前获取封禁级别进行判断就可以简单的实现了。

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK