用go封装一下临时token
本篇为用go设计开发一个自己的轻量级登录库/框架吧 的临时token篇,会讲讲临时token的实现,给库/框架增加新的功能。
Github:https://github.com/weloe/token-go
临时token也算是比较常见的业务,例如登录验证码信息,邀请链接等等,都属于临时token的范畴。
在服务器托管网token-go中同样使用Adapter组件进行了简单的封装。
封装思路
对于一个登录验证码,我们需要有创建,有效期,需要解析,需要能删除的功能。
因此,我们需要创建临时token,获取临时token有效期,解析临时token,删除临时token这几个方法。
而临时token会跟业务信息做关联,比如这个临时token是用于验证码服务或是用于邀请服务他们是互相隔离的,因此在存储的时候我们需要一个service参数做区分,我们存储为k,v结构,存储的key结构为: "token-go:" + "temp-token" + ":temp:" + service + ":" + token
,存储的value即为设定的对应的值。
最后决定出几个api
// Temp token api
CreateTempToken(token string, service string, value string, timeout int64) (string, error)
CreateTempTokenByStyle(style string, service string, value string, timeout int64) (string, error)
GetTempTokenTimeout(service string, tempToken string) int64
ParseTempToken(service string, tempToken string) string
DeleteTempToken(service string, tempToken string) error
代码实现
创建临时token
这里我们提供了两个方法,一个用于根据style使用内置创建token的函数创建token,另一个用于直接由开发者生成token再传入。创建token则是Adapter对信息进行存储。
通过指定style创建
htt服务器托管网ps://github.com/weloe/token-go/blob/90e576f01537c92b924670dee3e32b8d7f010585/enforcer_manager_api.go#L211
func (e *Enforcer) CreateTempTokenByStyle(style string, service string, value string, timeout int64) (string, error) {
token, err := e.generateFunc.Exec(style)
if err != nil {
return "", err
}
err = e.setTempToken(service, token, value, timeout)
if err != nil {
return "", err
}
return token, nil
}
指定token创建。
https://github.com/weloe/token-go/blob/90e576f01537c92b924670dee3e32b8d7f010585/enforcer_manager_api.go#L223
func (e *Enforcer) CreateTempToken(token string, service string, value string, timeout int64) (string, error) {
if token == "" {
return "", fmt.Errorf("token must not be empty")
}
err := e.setTempToken(service, token, value, timeout)
if err != nil {
return "", err
}
return token, nil
}
获取剩余时间
https://github.com/weloe/token-go/blob/90e576f01537c92b924670dee3e32b8d7f010585/enforcer_manager_api.go#L234
同样是使用Adapter组件去获取剩余时间
func (e *Enforcer) GetTempTokenTimeout(service string, tempToken string) int64 {
if tempToken == "" {
return constant.NotValueExpire
}
return e.getTimeoutByTempToken(service, tempToken)
}
func (e *Enforcer) getTimeoutByTempToken(service string, token string) int64 {
return e.adapter.GetTimeout(e.spliceTempTokenKey(service, token))
}
解析临时token
https://github.com/weloe/token-go/blob/90e576f01537c92b924670dee3e32b8d7f010585/enforcer_manager_api.go#L241
解析即是通过service,token去Adapter中获取对应的信息。
func (e *Enforcer) ParseTempToken(service string, tempToken string) string {
if tempToken == "" {
return ""
}
return e.getByTempToken(service, tempToken)
}
删除临时token
https://github.com/weloe/token-go/blob/90e576f01537c92b924670dee3e32b8d7f010585/enforcer_manager_api.go#L248
删除临时token则是从Adapter组件中删除对应的k,v数据
func (e *Enforcer) DeleteTempToken(service string, tempToken string) error {
return e.deleteByTempToken(service, tempToken)
}
测试
func TestEnforcer_TempToken(t *testing.T) {
enforcer, _ := NewTestEnforcer(t)
service := "code"
tempToken, err := enforcer.CreateTempToken("tempToken", service, "1234", -1)
if err != nil {
t.Fatalf("CreateTempToken() failed: %v", err)
}
if !reflect.DeepEqual(tempToken, "tempToken") {
t.Fatalf("token error, want is %v", "1234")
}
timeout := enforcer.GetTempTokenTimeout(service, tempToken)
if timeout != -1 {
t.Errorf("GetTempTokenTimeout() failed, unexpected timeout: %v", timeout)
}
codeValue := enforcer.ParseTempToken("code", tempToken)
if codeValue != "1234" {
t.Errorf("ParseTempToken() failed, unexpected codeValue: %v", codeValue)
}
// delete
if enforcer.DeleteTempToken(service, tempToken) != nil {
t.Fatalf("DeleteTempToken() failed: %v", err)
}
tokenTimeout := enforcer.GetTempTokenTimeout(service, tempToken)
if tokenTimeout != -2 {
t.Errorf("GetTempTokenTimeout() failed, unexpected tokenTimeout: %v", tokenTimeout)
}
codeValue = enforcer.ParseTempToken(service, tempToken)
if codeValue != "" {
t.Errorf("ParseTempToken() failed, unexpected codeValue: %v", codeValue)
}
// create token
tempToken, err = enforcer.CreateTempTokenByStyle("uuid", service, "1234", -1)
if err != nil {
t.Fatalf("CreateTempTokenByStyle() failed: %v", err)
}
// delete
if enforcer.DeleteTempToken(service, tempToken) != nil {
t.Fatalf("DeleteTempToken() failed: %v", err)
}
}
--- PASS: TestEnforcer_TempToken (0.01s)
PASS
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: List,Set,Map三者的区别,Java 创建对象有几种方式
一、List,Set,Map三者的区别 List(对付顺序的好帮手): List接口存储一组不唯一(可以有多个元素引用相同的对象),有序的对象 Set(注重独一无二的性质): 不允许重复的集合。不会有多个元素引用相同的对象。 Map(用Key来搜索的专家): …