首页 > 其他分享 >用go封装一下临时token

用go封装一下临时token

时间:2023-10-28 16:34:56浏览次数:36  
标签:err 封装 string service tempToken token go

用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创建

https://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

标签:err,封装,string,service,tempToken,token,go
From: https://www.cnblogs.com/weloe/p/17794231.html

相关文章

  • ASEMI高压二极管CL08-RG210参数,CL08-RG210封装
    编辑-ZCL08-RG210参数描述:型号:CL08-RG210反向重复峰值电压VRRM:8000V反向工作峰值电压VRWM:8000V正向平均电流IF:0.5A正向(不重复)浪涌电流IFSM:20A反向恢复时间trr:80ns正向峰值电压VFM:12V反向峰值电流IR:2uA工作环境和存贮温度Ta,TSTG:-40to+150℃  CL08-RG210封装大......
  • redis缓存更新策略,缓存穿透,缓存雪崩,缓存击穿。封装redis工具类
    (redis缓存)缓存是存储数据的临时地方,一般读写性能高1.给商铺添加缓存思路:在对应的serviceImpl里写逻辑@OverridepublicResultqueryById(Longid){Stringkey=CACHE_SHOP_KEY+id;//1.从redis查询商铺缓存StringshopJSON=stringRedisTemplate.opsF......
  • ASEMI高压二极管CL08-RG210参数,CL08-RG210封装
    编辑-ZCL08-RG210参数描述:型号:CL08-RG210反向重复峰值电压VRRM:8000V反向工作峰值电压VRWM:8000V正向平均电流IF:0.5A正向(不重复)浪涌电流IFSM:20A反向恢复时间trr:80ns正向峰值电压VFM:12V反向峰值电流IR:2uA工作环境和存贮温度Ta,TSTG:-40to+150℃ CL08-RG210封装大小:直径:7.5mm长度:2......
  • 如何使用SHC对Shell脚本进行二进制编译和封装
    在许多情况下,我们需要保护我们的shell脚本源码不被别人轻易查看。这时,使用shc工具将shell脚本编译成二进制文件是一个有效的方法。本文将详细介绍如何在线和离线条件下安装shc,并将其用于编译你的脚本。什么是SHC?shc是一个由C语言编写的Shell脚本加密程序,它可以将你的脚本编译成......
  • 【pwn】[MoeCTF 2022]babyfmt --格式化字符串漏洞,got表劫持
    拿到程序,先checksec一下发现是PartialRELRO,got表可修改当RELRO保护为NORELRO的时候,init.array、fini.array、got.plt均可读可写;为PARTIALRELRO的时候,ini.array、fini.array可读不可写,got.plt可读可写;为FULLRELRO时,init.array、fini.array、got.plt均可读不可写。然后看主......
  • 创建一个django项目
    1.创建一个django项目在pycharm里面创建一个django的新项目在项目配置的时候选择好第一个app,templates文件和python环境(在环境里要先下好django)我这里用的是conda管理的环境django里面的目录结构最外层的是本项目名字的一个app,一个users的app,templates模板文件,manages.py(......
  • 深入研究:Go语言文件写入的性能差异 原创 Go先锋 Go先锋
    深入研究:Go语言文件写入的性能差异原创 Go先锋 Go先锋 2023-10-2811:03 发表于广东收录于合集#Go语言包22个#性能效率1个Go先锋读完需要7分钟速读仅需3分钟  概述在Go语言开发中,文件操作是一个非常常见的任务。在不同的应用场景下,可能会面临选......
  • Python 框架学习 Django篇 (六) 数据表关联、ORM关联
    在后端服务器开发中,特别是前后端分离的架构中数据库是非常重要的,后端主要就是负责管理数据,而我们经常使用的mysql、oracle都是关系型数据库,什么是关系型数据库?就是建立在关系模型基础上的数据库,而最难处理的就是各个表之间的关联关系,一般这种关系分为三种:一对一、一对多、多对......
  • Python 框架学习 Django篇 (六) ORM关联
    像是上一章我们很少会通过页面点击去添加和绑定关系表,更多的时候都是通过django的语法实现,接下来我们做一个案例djangorom是怎么操作外键关系的创建mode模型表Django_demo/mgr/models.py#国家表classCountry(models.Model):name=models.CharField(max_length=100)#......
  • [TopCoder 13001] BigO 题解
    [TopCoder13001]BigO题解题目描述给定一张有向图,当\(L\)趋近于无穷大时,长度为\(L\)的路径条数有\(S\)条,此时若\(S=O(L^k)\),输出\(k\),否则如果没有多项式的大O表示法,输出\(-1\)。指数情况首先如果一张图中存在如下强连通分量,则\(S=O(2^L)\)。因为每次到1......