用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. iOS 百度导航没有语音播报

    1.百度地图没有语音播报 可以尝试如下方式: 1.tts确认相关key正确,可以放入官方demo测试 2.setting中 Product Name 尝试设置成英文,在info.plist设置Bund ...

  2. 【NestJS系列】从Nest CLI开始入门

    初识Nest JS Nest 是一个渐进的 Node.js 框架,它可以在 TypeScript 和 JavaScript (ES6.ES7.ES8)之上构建高效.可伸缩的企业级服务器端应用程序. N ...

  3. Kubernetes亲和性学习笔记

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是欣宸在学习Kubernetes调度器的 ...

  4. VBA与VB的区别

    从语言结构上讲,VBA是VB的一个子集,它们的语法结构是一样的.两者的开发环境也几乎相同.但是,VB是独立的开发工具,它不需要依附于任何其他应用程序,它有自己完全独立的工作环境和编译.链接系统.VBA ...

  5. 解决Avalonia 11.X版本的中文字体问题

    网上搜索的方法使用接口"IFontManagerImpl"这个方法目前只能用于Avalonia 10.X版本,因为11版本后官方把这个接口的成员都设置成了非plubic,所以之前的 ...

  6. Ansible快速复习

    本文章是上一篇ansible自动化运维的快速复习以及项目上用到的一些命令,针对长时间未使用ansible,导致命令忘记的同学,帮助快速回忆.详细内容还是看上一章'ansible自动化运维'. 查看版本 ...

  7. Python中字符串截取

    # 截取字符串时,如果位数不够,Python不会报错,而是返回空字符串 # 这是因为Python中的字符串是不可变的,所以当我们尝试访问一个不存在的索引时,Python会返回空字符串而不是报错 # 示 ...

  8. 数据可视化【原创】vue+arcgis+threejs 实现海量建筑物房屋渲染,性能优化

    本文适合对vue,arcgis4.x,threejs,ES6较熟悉的人群食用. 先报备一下版本号 "vue": "^2.6.11" "@arcgis/ ...

  9. 小白弄明白了 unix 时间戳的转换问题

    小白对于将 unix 时间戳转换为日期时间和使用日期时间转换为 unix 时间戳,在项目中见到过很多,每次使用时不是用现有的方法转换就是网上搜索方法. 小白见过各种转换方式觉得moment库很是方便, ...

  10. Vue.js 官方脚手架 create-vue 是怎么实现的?

    Vue.js 官方脚手架 create-vue 是怎么实现的? 摘要 本文共分为四个部分,系统解析了vue.js 官方脚手架 create-vue 的实现细节. 第一部分主要是一些准备工作,如源码下载 ...