Github仓库: https://github.com/weloe/token-go
token-go 致力于解决登录相关的问题,使用它可以更方便快速搭建一个项目中的用户登录相关模块,一键解决用户登录管理相关的问题。
例如:同一用户只能登录一次,同一用户多次登录多token,同一用户多次登录共享一个token,不同token生成方式,踢下线等等。
# 安装
```
go get github.com/weloe/token-go
```
# 使用默认配置
```go
import (
"fmt"
tokenGo "github.com/weloe/token-go"
"log"
"net/http"
)
var enforcer *tokenGo.Enforcer
func main() {
var err error
// use default adapter
adapter := tokenGo.NewDefaultAdapter()
enforcer, err = tokenGo.NewEnforcer(adapter)
// enable logger
enforcer.EnableLog()
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/user/login", Login)
http.HandleFunc("/user/isLogin", IsLogin)
log.Fatal(http.ListenAndServe(":8081", nil))
}
func Login(w http.ResponseWriter, req *http.Request) {
token, err := enforcer.Login("1", tokenGo.NewHttpContext(req, w))
if err != nil {
fmt.Fprintf(w, "Login error: %s\n", err)
}
fmt.Fprintf(w, "token: %s\n", token)
}
func IsLogin(w http.ResponseWriter, req *http.Request) {
login, err := enforcer.IsLogin(tokenGo.NewHttpContext(req, w))
if err != nil {
fmt.Fprintf(w, "IsLogin() = %v: %v", login, err)
}
fmt.Fprintf(w, "IsLogin() = %v", login)
}
```
# 自定义配置
同一用户只能登录一次:`IsConcurrent = false
&& IsShare = false`
同一用户多次登录共享一个token:`IsConcurrent = true &&
IsShare = false`
同一用户多次登录多token:`IsConcurrent = true && IsShare = true`
```go
import (
"fmt"
tokenGo "github.com/weloe/token-go"
"github.com/weloe/token-go/config"
"log"
"net/http"
)
var enforcer *tokenGo.Enforcer
func main() {
var err error
// use default adapter
adapter := tokenGo.NewDefaultAdapter()
tokenConfig := &config.TokenConfig{
TokenName: "uuid",
Timeout: 60,
IsReadCookie: true,
IsReadHeader: true,
IsReadBody: false,
IsConcurrent: true,
IsShare: true,
MaxLoginCount: -1,
}
enforcer, err = tokenGo.NewEnforcer(adapter, tokenConfig)
}
```
也可以从文件中读取配置信息
```yml
TokenConfig:
tokenStyle: uuid
tokenName: myTokenName
timeout: 2592000
dataRefreshPeriod: 30
isConcurrent: true
isShare: true
maxLoginCount: 12
isReadBody: true
isReadHeader: true
isReadCookie: true
isWriteHeader: false
```
```go
enforcer, err = tokenGo.NewEnforcer(adapter, filepath)
```
# 权限校验
此外还提供简单的权限校验
```go
type ACL interface {
GetPermission(id string) []string
}
```
```go
type RBAC interface {
GetRole(id string) []string
}
```
实现这两个接口中的任意一个并调用`enforcer.SetAuth(model)`
之后就可以使用这两个api进行权限校验
``` go
// 实现RBAC接口后可使用
CheckRole(ctx ctx.Context, role string) error
// 实现ACL接口后可使用
CheckPermission(ctx ctx.Context, permission string) error
```
## 使用示例
```go
type MockRbacAuth struct {
}
func (m *MockRbacAuth) GetRole(id string) []string {
var arr = make([]string, 2)
arr[1] = "user"
return arr
}
type MockAclAuth struct {
}
func (m *MockAclAuth) GetPermission(id string) []string {
var arr = make([]string, 2)
arr[1] = "user::get"
return arr
}
func TestEnforcer_CheckRole(t *testing.T) {
err, enforcer, ctx := NewTestEnforcer(t)
if err != nil {
t.Errorf("NewTestEnforcer() failed: %v", err)
}
m := &MockRbacAuth{}
enforcer.SetAuth(m)
loginModel := model.DefaultLoginModel()
loginModel.Token = "233"
_, err = enforcer.LoginByModel("id", loginModel, ctx)
if err != nil {
t.Errorf("Login() failed: %v", err)
}
err = enforcer.CheckRole(ctx, "user")
if err != nil {
t.Errorf("CheckRole() failed: %v", err)
}
err = enforcer.CheckPermission(ctx, "user::get")
if err == nil {
t.Errorf("CheckRole() failed")
}
t.Logf("CheckPermission() return %v", err)
}
```
# Api
``` go
// 登录
Login(id string, ctx ctx.Context) (string, error)
// 指定参数登录
LoginByModel(id string, loginModel *model.Login, ctx ctx.Context) (string, error)
// 退出
Logout(ctx ctx.Context) error
// 判断是否登录
IsLogin(ctx ctx.Context) (bool, error)
IsLoginById(id string) (bool, error)
// 获得当前登录的id
GetLoginId(ctx ctx.Context) (string, error)
// 获取账号的登录数量
GetLoginCount(id string) int
// 模拟顶其他账号下线
Replaced(id string, device string) error
// 把其他账号踢下线
Kickout(id string, device string) error
// 获取当前的token
GetRequestToken(ctx ctx.Context) string
// 添加自定义的token生成方法
AddTokenGenerateFun(tokenStyle string, f model.GenerateFunc) error
//检查是否登录
CheckLogin(ctx ctx.Context) error
SetAuth(manager interface{})
// 检查是否有该角色
CheckRole(ctx ctx.Context, role string) error
// 检查是否有该权限
CheckPermission(ctx ctx.Context, permission string) error
```
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传