用go封装一下二级认证功能

打印 上一主题 下一主题

主题 885|帖子 885|积分 2655

用go封装一下二级认证

本篇为用go设计开发一个自己的轻量级登录库/框架吧 - 秋玻 - 博客园 (cnblogs.com)的二级认证业务篇,会讲讲二级认证业务的实现,给库/框架增加新的功能。
源码:https://github.com/weloe/token-go
在一个系统中,为了保证账号安全性,我们除了登录之外可能还会进行二次校验,例如游戏中的交易密码认证,博客园登录的两步验证等等。因此,我打算为token-go封装下二级认证的功能。
实现思路

对于二级认证我们的认证对象是token也就是一个登录对象,为了兼容各种业务还要加上service业务,最后就是这个认证生效的时间time,毕竟总不能一次认证过了以后就再也不用认证了,那这个二级认证的功能也就没有意义了。
在业务上我们往往需要的四个方法,执行认证,判断是否认证,查看认证生效的剩余时间,取消认证(让认证失效)。
从代码实现上看
认证需要存储token-service信息
判断是否认证有效(是否在认证时间内)就是去判断这个token-service信息是否存在了
查看认证生效的剩余时间就是获取一下token-service的剩余存储时间
取消认证(让认证失效)也就是手动去删除这个token-service信息了,一般来说在退出登录的时候需要取消认证信息。
而存储删除等持久化操作则使用Adapter
https://github.com/weloe/token-go/blob/9d1a8be2c16559d46460c82b33995b789e6e31c4/enforcer_interface.go#L58
  1.         OpenSafe(token string, service string, time int64) error
  2.         IsSafe(token string, service string) bool
  3.         GetSafeTime(token string, service string) int64
  4.         CloseSafe(token string, service string) error
复制代码
代码实现

有了思路后代码实现其实就很简单了,无非就是存储信息,判断信息是否存在和删除信息了。
执行认证

https://github.com/weloe/token-go/blob/9d1a8be2c16559d46460c82b33995b789e6e31c4/enforcer.go#L646
首先校验参数,在执行认证前需要判断一下是否登录,不然怎么说是二级认证?存储token和service信息,调用logger,最后调用watcher提供扩展点。
  1. func (e *Enforcer) OpenSafe(token string, service string, time int64) error {
  2.         if time == 0 {
  3.                 return nil
  4.         }
  5.         // 判断是否登录
  6.         err := e.CheckLoginByToken(token)
  7.         if err != nil {
  8.                 return err
  9.         }
  10.         err = e.adapter.SetStr(e.spliceSecSafeKey(token, service), constant.DefaultSecondAuthValue, time)
  11.         if err != nil {
  12.                 return err
  13.         }
  14.         if e.watcher != nil {
  15.                 e.watcher.OpenSafe(e.loginType, token, service, time)
  16.         }
  17.         return nil
  18. }
复制代码
判断是否认证

https://github.com/weloe/token-go/blob/ac8674dc3ebbd4bcb213328b43f4c11678191919/enforcer.go#L665
判断是否认证即是判断token-service信息是否存在。
  1. func (e *Enforcer) IsSafe(token string, service string) bool {
  2.         if token == "" {
  3.                 return false
  4.         }
  5.         str := e.adapter.GetStr(e.spliceSecSafeKey(token, service))
  6.         return str != ""
  7. }
复制代码
查看认证生效的剩余时间

https://github.com/weloe/token-go/blob/ac8674dc3ebbd4bcb213328b43f4c11678191919/enforcer.go#L673
  1. func (e *Enforcer) GetSafeTime(token string, service string) int64 {
  2.         if token == "" {
  3.                 return 0
  4.         }
  5.         timeout := e.adapter.GetTimeout(e.spliceSecSafeKey(token, service))
  6.         return timeout
  7. }
复制代码
取消认证

https://github.com/weloe/token-go/blob/ac8674dc3ebbd4bcb213328b43f4c11678191919/enforcer.go#L681
取消就是使用adapter删除token-service的信息
  1. func (e *Enforcer) CloseSafe(token string, service string) error {
  2.         if token == "" {
  3.                 return nil
  4.         }
  5.         err := e.adapter.DeleteStr(e.spliceSecSafeKey(token, service))
  6.         if err != nil {
  7.                 return err
  8.         }
  9.         if e.watcher != nil {
  10.                 e.watcher.CloseSafe(e.loginType, token, service)
  11.         }
  12.         return nil
  13. }
复制代码
测试

https://github.com/weloe/token-go/blob/9d1a8be2c16559d46460c82b33995b789e6e31c4/enforcer_test.go#L478
  1. func TestEnforcer_SecSafe(t *testing.T) {
  2.         err, enforcer, _ := NewTestEnforcer(t)
  3.         if err != nil {
  4.                 t.Fatalf("NewTestEnforcer() failed: %v", err)
  5.         }
  6.         tokenValue, err := enforcer.LoginById("1")
  7.         if err != nil {
  8.                 t.Fatalf("LoginById() failed: %v", err)
  9.         }
  10.         service := "default_service"
  11.         err = enforcer.OpenSafe(tokenValue, service, 600000)
  12.         if err != nil {
  13.                 t.Fatalf("OpenSafe() failed: %v", err)
  14.         }
  15.         isSafe := enforcer.IsSafe(tokenValue, service)
  16.         if !isSafe {
  17.                 t.Fatalf("IsSafe() failed, unexpected return value: %v", isSafe)
  18.         }
  19.         time := enforcer.GetSafeTime(tokenValue, service)
  20.         t.Logf("safe time is %v", time)
  21.         err = enforcer.CloseSafe(tokenValue, service)
  22.         if err != nil {
  23.                 t.Fatalf("CloseSafe() failed: %v", err)
  24.         }
  25.         time = enforcer.GetSafeTime(tokenValue, service)
  26.         if time != constant.NotValueExpire {
  27.                 t.Fatalf("error safe time: %v", time)
  28.         }
  29.         isSafe = enforcer.IsSafe(tokenValue, service)
  30.         if isSafe {
  31.                 t.Fatalf("IsSafe() failed, unexpected return value: %v", isSafe)
  32.         }
  33. }
复制代码
  1. === RUN   TestEnforcer_SecSafe
  2. 2023/10/02 20:56:00 timer period = 30, timer start
  3.     enforcer_test.go:497: safe time is 600000
  4. --- PASS: TestEnforcer_SecSafe (0.01s)
  5. PASS
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

风雨同行

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表