首页 > 其他分享 >用go设计开发一个自己的轻量级登录库/框架吧

用go设计开发一个自己的轻量级登录库/框架吧

时间:2023-05-06 18:22:54浏览次数:59  
标签:string 登录 interface token bool error go 轻量级

用go设计开发一个自己的轻量级登录库/框架吧

几乎每个项目都会有登录,退出等用户功能,而登录又不单仅仅是登录,我们要考虑很多东西。

token该怎么生成?生成什么样的?

是在Cookie存token还是请求头存token?读取的时候怎么读取?

允许同一个账号被多次登录吗?多次登录他们的token是一样的?还是不一样的?

登录也有可能分成管理员登录,用户登录等多种登录类型

我们要做的就是把这些东西封装到一起,然后能更方便的使用

而完成这些最难的就是如何设计架构了,其实要简单的封装一下并不难,本篇要讲的就是如何进行架构的设计了。

源码:weloe/token-go: a light login library (github.com)

Enforcer

我们可以抽象出一个供外部调用的执行器,它包括以下几个部分

token-go/enforcer.go at master · weloe/token-go (github.com)

type Enforcer struct {
    // 从配置文件读取配置需要
	conf         string
    // 登录类型
	loginType    string
	config       config.TokenConfig
    // 生成token的函数
	generateFunc model.GenerateTokenFunc
    // 用于存储数据
	adapter      persist.Adapter
    // 监听器
	watcher      persist.Watcher
    // web上下文
	webCtx       ctx.Context
    // 用于记录日志
	logger       log.Logger
}

执行器的接口,包含供外部调用的方法

token-go/enforcer_interface.go at master · weloe/token-go · GitHub

var _ IEnforcer = &Enforcer{}

type IEnforcer interface {
    
	Login(id string) (string, error)
	LoginByModel(id string, loginModel *model.Login) (string, error)
	Logout() error
	IsLogin() (bool, error)
	IsLoginById(id string) (bool, error)
	GetLoginId() (string, error)

	Replaced(id string, device string) error
	Kickout(id string, device string) error

	GetRequestToken() string

	SetType(t string)
	GetType() string
	SetContext(ctx ctx.Context)
	GetAdapter() persist.Adapter
	SetAdapter(adapter persist.Adapter)
	SetWatcher(watcher persist.Watcher)
	SetLogger(logger log.Logger)
	EnableLog()
	IsLogEnable() bool
	GetSession(id string) *model.Session
	SetSession(id string, session *model.Session, timeout int64) error
}

Config

首先就是根据需求抽象出配置信息

一个是cookie的配置

token-go/cookie.go at master · weloe/token-go · GitHub

type CookieConfig struct {
	Domain   string
	Path     string
	Secure   bool
	HttpOnly bool
	SameSite string
}

一个是token的配置

token-go/token.go at master · weloe/token-go · GitHub

type TokenConfig struct {
   // TokenStyle
   // uuid | uuid-simple | random-string32 | random-string64 | random-string128
   TokenStyle string
    
   TokenName   string

   Timeout int64

   // 允许多次登录
   IsConcurrent bool
   // 多次登录共享一个token
   IsShare bool
   // If (IsConcurrent == true && IsShare == false)才支持配置
   // If IsConcurrent == -1, 不检查登录数量
   MaxLoginCount int16

   // 读取token的方式
   IsReadBody   bool
   IsReadHeader bool
   IsReadCookie bool

   // 是否把token写入响应头
   IsWriteHeader bool

   CookieConfig *CookieConfig
}

Adapter

adapter是底层用来存储数据的结构,为了兼容不同的实现(不同的存储方式),设计成一个接口。

token-go/adapter.go at master · weloe/token-go · GitHub

type Adapter interface {

	// GetStr string operate string value
	GetStr(key string) string
	// SetStr set store value and timeout
	SetStr(key string, value string, timeout int64) error
	// UpdateStr only update value
	UpdateStr(key string, value string) error
	// DeleteStr delete string value
	DeleteStr(key string) error
	// GetStrTimeout get expire
	GetStrTimeout(key string) int64
	// UpdateStrTimeout update expire time
	UpdateStrTimeout(key string, timeout int64) error

	// Get get interface{}
	Get(key string) interface{}
	// Set store interface{}
	Set(key string, value interface{}, timeout int64) error
	// Update only update interface{} value
	Update(key string, value interface{}) error
	// Delete delete interface{} value
	Delete(key string) error
	// GetTimeout get expire
	GetTimeout(key string) int64
	// UpdateTimeout update timeout
	UpdateTimeout(key string, timeout int64) error
}

Context

我们需要从请求读取token,可能也需要写出token,因此需要兼容不同的web上下文,我们需要设计一个Context接口

token-go/context.go at master · weloe/token-go · GitHub

type Context interface {
	Request() Request
	Response() Response
	ReqStorage() ReqStorage
	MatchPath(pattern string, path string) bool
	IsValidContext() bool
}

Watcher

监听器,用于在一些事件发生的时候进行一些其他操作。

token-go/watcher.go at master · weloe/token-go · GitHub

// Watcher event watcher
type Watcher interface {
	// Login called after login
	Login(loginType string, id interface{}, tokenValue string, loginModel *model.Login)
	// Logout called after logout
	Logout(loginType string, id interface{}, tokenValue string)
}

Logger

Logger,用于记录日志,方便debug等等,需要设计成可以自由开启关闭。

token-go/logger.go at master · weloe/token-go · GitHub

type Logger interface {
	persist.Watcher

	// Enable turn on or off
	Enable(bool bool)

	// IsEnabled return if logger is enabled
	IsEnabled() bool
}

到此,项目的大致的结构就设计完成,下一篇会讲讲本业务的具体实现

标签:string,登录,interface,token,bool,error,go,轻量级
From: https://www.cnblogs.com/weloe/p/17378215.html

相关文章

  • MongoDB 从 mysql等数据库中导入数据
    关键字:MongoDB从mysql等数据库中导入数据一、向mongodb数据库导入数据在MongoVUE中选择一个数据库右键import然后填写mysql等数据库的连接信息点击import即可导入!......
  • mongodb分布式安装部署
    关键字:mongodb分布式安装部署附件是mongodb服务器分布式部署权威文档:其他不错的集群参考文章:搭建高可用MongoDB集群(一):配置MongoDB:http://blog.jobbole.com/72610/搭建高可用MongoDB集群(二):副本集:http://blog.jobbole.com/72624/搭建高可用MongoDB......
  • xshell登录服务器提示符显示-bash-4.2#解决方法
    xshell登录服务器提示符显示-bash-4.2#解决方法突然发现root登录的xshell的终端提示符显示的是-bash-4.2#而不是root@主机名+路径的显示方式。搞了半天也不知道为什么出现这种情况。今天终于搞定这个问题,原因是root在/root下面的几个配置文件丢失,丢失文件如下:1、.bash_pro......
  • django中间件
    目录一、django中间件什么是中间件?如何自定义中间件二、django中间件三个了解的方法三、django中间件五个方法的执行流程详解四、基于django中间件的功能设计功能设计介绍如何利用字符串导入模块功能模拟一、django中间件什么是中间件?官方的说法:中间件是一个用来处理Django的......
  • SpringBoot 操作 MongoDB 新增和查询
    MongoDBJAVA新增+查询上接SpringBoot整合MongoDB,记一下MongoDB的CRUD方法。Create新增使用MongoRepository方式的新增非常简单,之前的整合中已经尝试过,这里再总结一下:首先需要有对应的实体类对象:@Data@AllArgsConstructor@NoArgsConstructor@ToStringpublicc......
  • django内置序列化组件(drf前身)
    目录一、django内置序列化组件(drf前身)一、django内置序列化组件(drf前身)一、django内置序列化组件(drf前身)这里的内置序列化组件,其实就是实现将后端数据,存放到字典中或是存放到列表中有序输出。这里是我们用JsonResponse模块自己实现的代码'''前后端分离的项目视图函数......
  • django分页器
    目录一、分页器思路二、自定义分页器的使用一、分页器思路分页器主要听处理逻辑代码最后很简单推导流程 1.queryset支持切片操作(正数) 2.研究各个参数之间的数学关系 每页固定展示多少条数据、起始位置、终止位置 3.自定义页码参数 current_page=request.GET......
  • django视图层与cbv源码分析
    目录一、视图层之必会三板斧二、JsonResponse对象两种序列化数据的方式方式一:使用json模块方式二:使用JsonResponse对象使用JsonResponse对象序列化除字典外的数据类型如果给JsonResponse对象内部的json代码传参三、视图层之request对象获取文件四、视图层之FBV与CBV概念介绍五、CB......
  • django模板层
    目录一、模板层1.模板语法传值2.模板语法传值特性3.模板语法之过滤器(内置函数)lengthsliceaddfilesizeformatdatetruncatecharstruncatewordssafe二、模板层之标签分支结构iffor循环with(定义变量名)三、自定义过滤器、标签及inclusion_tag(了解)四、母版(模板)的继承与导入(重要)......
  • django生命周期流程图与django路由层
    目录一、django请求生命周期流程图二、django路由层1.路由匹配2.转换器3.正则匹配不同版本的区别正则匹配斜杠导致的区别4、正则匹配的无名有名分组分组匹配无名分组有名分组三、反向解析1.引入反向解析2.反向解析使用3.有名无名反向解析(动态路由反向解析)四、路由分发五、名称空间......