用go封装一下临时token

本篇为用go设计开发一个自己的轻量级登录库/框架吧的临时token篇,会讲讲临时token的实现,给库/框架增加新的功能。

Github:https://github.com/weloe/token-go

临时token也算是比较常见的业务,例如登录验证码信息,邀请链接等等,都属于临时token的范畴。

在token-go中同样使用Adapter组件进行了简单的封装。

封装思路

对于一个登录验证码,我们需要有创建,有效期,需要解析,需要能删除的功能。

因此,我们需要创建临时token,获取临时token有效期,解析临时token,删除临时token这几个方法。

而临时token会跟业务信息做关联,比如这个临时token是用于验证码服务或是用于邀请服务他们是互相隔离的,因此在存储的时候我们需要一个service参数做区分,所以存储的key结构为: "token-go:" + "temp-token" + ":temp:" + service + ":" + token

最后决定出几个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

用go封装一下临时token的更多相关文章

  1. http post url参数封装(key token 及校验码)

    post请求本来是一种很常见的web请求方式,相信许多项目都有一系列的封装工具类. 今天遇着一个特殊的需求. 需要在post的请求url内封装相应的token 与及key相关的值,这就奇怪了,url封 ...

  2. vue axios封装以及登录token过期跳转问题

    Axios配置JWT/封装插件/发送表单数据 首先请务必已仔细阅读 Axios 文档并熟悉 JWT: 中文文档 JWT 中文文档 安装 npm install axios npm install es ...

  3. WebApi基于Token和签名的验证

    最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久 ...

  4. 自定义shiro的Realm实现和CredentialsMatcher实现以及Token实现

    Realm是shiro比较核心的接口,简单说它的实现类就是校验用户输入的账号信息的地方.如果想自定义实现一般的配置文件如下: <!--自定义Realm 继承自AuthorizingRealm - ...

  5. 接口自动化框架(java)--4.接口Token传递

    这套框架的报告是自己封装的 一般token会在登录接口返回结果中呈现,从代码层面获取token的方式有很多种,我是使用jsonpath这个json路径语言去匹配token所在路径的key值 packa ...

  6. 将以太坊封装为 ERC20

    将以太坊封装为 ERC20 TOKEN 很多 DAPP 都是在处理 ERC20接口的 token, 其实很容易将以太坊封装为 ERC20,这样就可以统一处理, 至少我目前在做的雷电网络就是这么处理的. ...

  7. 鉴权应用服务器 app客户端 web服务端 安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)

    设置EndPoint和凭证 移动终端是一个不受信任的环境,把AccessKeyId和AccessKeySecret直接保存在终端用来加签请求,存在极高的风险.建议只在测试时使用明文设置模式,业务应用推 ...

  8. Spring Boot中微信全局token的缓存实现

    为什么要缓存token? 这里的token指的是微信JSAPI中基础支持的ACCESS_TOKEN,并非网页授权ACCESS_TOKEN.网页授权Token每天的调用次数没有限制,不需要缓存. 接口 ...

  9. 必备技能四、ajax及token

    转https://segmentfault.com/a/1190000008470355?utm_source=tuicool&utm_medium=referral 转 https://ww ...

  10. 配置项目请求地址和axios以及实现token过期无痛刷新

    配置请求地址:config->index.js 一个项目里通常有一个config->index.js,该文件包含了当前项目的请求地址,以及项目的版本信息. // 请求地址 const AP ...

随机推荐

  1. 2023河南省ICPC大学生程序设计竞赛-wh

    第一次出去比赛,首先感谢程老师选择我们新生更多的比赛机会,感谢! 在周六我们一起做了高铁出发取洛阳参加icpc河南省赛,不得不说洛阳师范学院确实环境很好看..在热身赛时,已经被泼了冷水,这C也太难了, ...

  2. Nginx:超时 keeplive_timeout 配置

    参考:Nginx的超时keeplive_timeout配置详解 HTTP 是一种无状态协议,客户端向服务器发送一个 TCP 请求,服务端响应完毕后断开连接. 如果客户端向服务器发送多个请求,每个请求都 ...

  3. Flutter状态管理-FlyingRedux

    简介 Flying Redux 是一个基于Redux状态管理的组装式flutter应用框架. 它有四个特性: 函数式编程 可预测的状态 插拔式的组件化 支持null safety 和 flutter ...

  4. [git]记配置本地git到gitlab并推送

    前言 gitlab仓库地址:git@192.168.0.12:godev/gohello.git 步骤 # 配置用户 git config --global user.name "zhang ...

  5. vivo 场景下的 H5无障碍适配实践

    作者:vivo 互联网前端团队- Zhang Li.Dai Wenkuan 随着信息无障碍的建设越来越受重视,开发人员在无障碍适配中也遇到了越来越多的挑战.本文是笔者在vivo开发H5项目做无障碍适配 ...

  6. 【腾讯云 Cloud Studio 实战训练营】在线 IDE 编写 canvas 转换黑白风格头像

    关于 Cloud Studio Cloud Studio 是基于浏览器的集成式开发环境(IDE),为开发者提供了一个永不间断的云端工作站.用户在使用Cloud Studio 时无需安装,随时随地打开浏 ...

  7. CF992E Nastya and King-Shamans 题解

    传送门 分析 由于满足 \(a_i\ge0\),所以 \(s_i\) 单调不减. 当我们找到一个 \(i\) 时,不管 \(i\) 是否满足,下一个可能的一定大于等于 \(a_i+s_{i-1}\). ...

  8. cs50ai0----search

    cs50ai0-------Search cs50ai0-------Search 基础知识 课后题目 代码实践 学习链接 总结 基础知识 (1) search problem 上图是搜索问题的一般形 ...

  9. P4327题解

    思路 分组计算 以下图为例: ..#.. .#.. .*.. .#.. .#.#. #.#. *.*. #.#. #.X.# .X.* .X.* .X.# .#.#. #.#. *.*. #.#. . ...

  10. 《数据结构-C语言》单链表

    @ 目录 单链表 结构定义 初始化 建立 清空 求表长 判断是否为空表 取值 查找 插入 删除 销毁 遍历打印 测试 单链表 结构定义 #include <stdio.h> #includ ...