token设计

This commit is contained in:
yumaojun03 2025-05-31 10:50:37 +08:00
parent c176c4086f
commit cc4729de15
11 changed files with 298 additions and 45 deletions

View File

@ -10,3 +10,18 @@
鉴权: 你能干什么(范围)
## 概要设计
针对问题(需求),给出一种解决方案(解题)
![](./design.drawio)
## 详细设计
定义业务

View File

@ -1,2 +1,20 @@
# 令牌管理
+ 颁发访问令牌: Login
+ 撤销访问令牌: 令牌失效了 Logout
+ 校验访问令牌:检查令牌的合法性, 是不是伪造的
## 详情设计的时候
字段(业务需求)
令牌:
+ 过期时间
+ 颁发时间
+ 被颁发的人
+ ...
问题: 无刷新功能, 令牌到期了,自动退出了, 过期时间设置长一点, 长时间不过期 又有安全问题
1. 业务功能: 令牌的刷新, 令牌过期了过后,允许用户进行刷新(需要使用刷新Token来刷新 刷新Token也是需要有过期时间 这个时间决定回话长度)有了刷新token用户不会出现 使用中被中断的情况, 并且长时间未使用,系统也户自动退出(刷新Token过期)

View File

@ -0,0 +1,31 @@
package token
type SOURCE int
const (
// 未知
SOURCE_UNKNOWN SOURCE = iota
// Web
SOURCE_WEB
// IOS
SOURCE_IOS
// ANDROID
SOURCE_ANDROID
// PC
SOURCE_PC
// API 调用
SOURCE_API SOURCE = 10
)
type LOCK_TYPE int
const (
// 用户退出登录
LOCK_TYPE_REVOLK LOCK_TYPE = iota
// 刷新Token过期, 回话中断
LOCK_TYPE_TOKEN_EXPIRED
// 异地登陆
LOCK_TYPE_OTHER_PLACE_LOGGED_IN
// 异常Ip登陆
LOCK_TYPE_OTHER_IP_LOGGED_IN
)

View File

@ -0,0 +1,70 @@
package token
import (
"context"
"time"
)
type Service interface {
// 颁发访问令牌: Login
IssueToken(context.Context, *IssueTokenRequest) (*Token, error)
// 撤销访问令牌: 令牌失效了 Logout
RevolkToken(context.Context, *RevolkTokenRequest) (*Token, error)
// 校验访问令牌:检查令牌的合法性, 是不是伪造的
ValidateToken(context.Context, *ValidateTokenRequest) (*Token, error)
}
// 用户会给我们 用户的身份凭证用于换取Token
type IssueTokenRequest struct {
// 端类型
Source SOURCE `json:"source"`
// 认证方式
Issuer string `json:"issuer"`
// 参数
Parameter IssueParameter `json:"parameter"`
}
type IssueParameter map[string]any
/*
password issuer parameter
*/
func (p IssueParameter) Username() string {
return GetIssueParameterValue[string](p, "username")
}
func (p IssueParameter) Password() string {
return GetIssueParameterValue[string](p, "password")
}
func (p IssueParameter) SetUsername(v string) {
p["username"] = v
}
func (p IssueParameter) SetPassword(v string) {
p["password"] = v
}
/*
private token issuer parameter
*/
func (p IssueParameter) AccessToken() string {
return GetIssueParameterValue[string](p, "access_token")
}
func (p IssueParameter) ExpireTTL() time.Duration {
return time.Second * time.Duration(GetIssueParameterValue[int64](p, "expired_ttl"))
}
func (p IssueParameter) SetAccessToken(v string) {
p["access_token"] = v
}
type RevolkTokenRequest struct {
}
type ValidateTokenRequest struct {
}

View File

@ -0,0 +1,67 @@
package token
import "time"
// 需要存储到数据库里面的对象(表)
type Token struct {
// 在添加数据需要, 主键
Id uint64 `json:"id" gorm:"column:id;type:uint;primary_key;"`
// 用户来源
Source SOURCE `json:"source" gorm:"column:source;type:tinyint(1);index" description:"用户来源"`
// 颁发器, 办法方式(user/pass )
Issuer string `json:"issuer" gorm:"column:issuer;type:varchar(100);index" description:"颁发器"`
// 该Token属于哪个用户
UserId uint64 `json:"user_id" gorm:"column:user_id;index" description:"持有该Token的用户Id"`
// 用户名
UserName string `json:"user_name" gorm:"column:user_name;type:varchar(100);not null;index" description:"持有该Token的用户名称"`
// 是不是管理员
IsAdmin bool `json:"is_admin" gorm:"column:is_admin;type:tinyint(1)" description:"是不是管理员"`
// 令牌生效空间Id
NamespaceId uint64 `json:"namespace_id" gorm:"column:namespace_id;type:uint;index" description:"令牌所属空间Id"`
// 令牌生效空间名称
NamespaceName string `json:"namespace_name" gorm:"column:namespace_name;type:varchar(100);index" description:"令牌所属空间"`
// 访问范围定义, 鉴权完成后补充
Scope map[string]string `json:"scope" gorm:"column:scope;type:varchar(100);serializer:json" description:"令牌访问范围定义"`
// 颁发给用户的访问令牌(用户需要携带Token来访问接口)
AccessToken string `json:"access_token" gorm:"column:access_token;type:varchar(100);not null;uniqueIndex" description:"访问令牌"`
// 访问令牌过期时间
AccessTokenExpiredAt *time.Time `json:"access_token_expired_at" gorm:"column:access_token_expired_at;type:timestamp;index" description:"访问令牌的过期时间"`
// 刷新Token
RefreshToken string `json:"refresh_token" gorm:"column:refresh_token;type:varchar(100);not null;uniqueIndex" description:"刷新令牌"`
// 刷新Token过期时间
RefreshTokenExpiredAt *time.Time `json:"refresh_token_expired_at" gorm:"column:refresh_token_expired_at;type:timestamp;index" description:"刷新令牌的过期时间"`
// 创建时间
IssueAt time.Time `json:"issue_at" gorm:"column:issue_at;type:timestamp;default:current_timestamp;not null;index" description:"令牌颁发时间"`
// 更新时间
RefreshAt *time.Time `json:"refresh_at" gorm:"column:refresh_at;type:timestamp" description:"令牌刷新时间"`
// 令牌状态
Status *Status `json:"status" gorm:"embedded" modelDescription:"令牌状态"`
// 其他扩展信息
Extras map[string]string `json:"extras" gorm:"column:extras;serializer:json;type:json" description:"其他扩展信息"`
}
func NewStatus() *Status {
return &Status{}
}
type Status struct {
// 冻结时间
LockAt *time.Time `json:"lock_at" bson:"lock_at" gorm:"column:lock_at;type:timestamp;index" description:"冻结时间"`
// 冻结类型
LockType LOCK_TYPE `json:"lock_type" bson:"lock_type" gorm:"column:lock_type;type:tinyint(1)" description:"冻结类型 0:用户退出登录, 1:刷新Token过期, 回话中断, 2:异地登陆, 异常Ip登陆" enum:"0|1|2|3"`
// 冻结原因
LockReason string `json:"lock_reason" bson:"lock_reason" gorm:"column:lock_reason;type:text" description:"冻结原因"`
}
func (s *Status) SetLockAt(v time.Time) {
s.LockAt = &v
}
func (s *Status) ToMap() map[string]any {
return map[string]any{
"lock_at": s.LockAt,
"lock_type": s.LockType,
"lock_reason": s.LockReason,
}
}

View File

@ -0,0 +1,13 @@
package token
// 泛型函数
func GetIssueParameterValue[T any](p IssueParameter, key string) T {
v := p[key]
if v != nil {
if value, ok := v.(T); ok {
return value
}
}
var zero T
return zero
}

View File

@ -1,144 +1,159 @@
<mxfile host="65bd71144e">
<diagram id="kBUSl4Twz2xUubsumQ87" name="第 1 页">
<mxGraphModel dx="830" dy="442" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxGraphModel dx="892" dy="554" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="24" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="24" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="380" y="230" width="330" height="180" as="geometry"/>
</mxCell>
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="60" y="230" width="320" height="180" as="geometry"/>
</mxCell>
<mxCell id="3" value="client" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="3" value="client" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="60" y="90" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="4" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="3">
<mxCell id="4" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="3" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="120" y="226" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="5" value="HTTP API" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="4">
<mxCell id="5" value="HTTP API" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="4" vertex="1" connectable="0">
<mxGeometry x="-0.1648" y="6" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="6" value="Basic Auth: base64(用户名:密码)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxCell id="6" value="Basic Auth: base64(用户名:密码)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="160" y="170" width="180" height="30" as="geometry"/>
</mxCell>
<mxCell id="9" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="7" target="8">
<mxCell id="9" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="7" target="8" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="10" value="user/pass" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9">
<mxCell id="10" value="user/pass" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9" vertex="1" connectable="0">
<mxGeometry x="-0.0981" y="-3" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="7" value="权限拦截器" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="7" value="权限拦截器" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="70" y="250" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="8" value="用户模块" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="8" value="用户模块" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="250" y="250" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="11" value="client" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="11" value="client" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="380" y="90" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="12" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="11">
<mxCell id="12" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="11" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="440" y="230" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="13" value="基于访问令牌" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxCell id="13" value="基于访问令牌" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="460" y="170" width="180" height="30" as="geometry"/>
</mxCell>
<mxCell id="17" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="15" target="16">
<mxCell id="17" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="15" target="16" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="18" value="用自己的身份信息 换一个凭证&lt;div&gt;1. user/pass&lt;/div&gt;&lt;div&gt;2. 手机登录&lt;/div&gt;&lt;div&gt;3. 三分认证: 飞书/支付宝&lt;/div&gt;&lt;div&gt;4. LDAP 凭证&lt;/div&gt;&lt;div&gt;...&lt;/div&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="17">
<mxCell id="18" value="用自己的身份信息 换一个凭证&lt;div&gt;1. user/pass&lt;/div&gt;&lt;div&gt;2. 手机登录&lt;/div&gt;&lt;div&gt;3. 三分认证: 飞书/支付宝&lt;/div&gt;&lt;div&gt;4. LDAP 凭证&lt;/div&gt;&lt;div&gt;...&lt;/div&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="17" vertex="1" connectable="0">
<mxGeometry x="0.3099" y="-1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="15" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxCell id="15" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
<mxGeometry x="730" y="60" width="30" height="60" as="geometry"/>
</mxCell>
<mxCell id="16" value="令牌颁发" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="16" value="令牌颁发" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="570" y="250" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="19" value="业务服务" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="19" value="业务服务" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="80" y="350" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="20" value="业务服务" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="20" value="业务服务" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="390" y="350" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="21" value="业务服务" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="21" value="业务服务" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="580" y="350" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="23" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="22" target="16">
<mxCell id="23" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="22" target="16" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="22" value="权限拦截器" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="22" value="权限拦截器" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="390" y="250" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="25" value="操作&lt;div&gt;具体的接口&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="25" value="操作&lt;div&gt;具体的接口&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="560" y="510" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="32" style="edgeStyle=none;html=1;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="26" target="29">
<mxCell id="32" style="edgeStyle=none;html=1;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="26" target="29" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="26" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxCell id="26" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
<mxGeometry x="110" y="500" width="30" height="60" as="geometry"/>
</mxCell>
<mxCell id="27" value="Who&amp;nbsp; &amp;nbsp; &amp;nbsp;角色&amp;nbsp; &amp;nbsp;Namespace&lt;div&gt;A&amp;nbsp; 开发 项目A&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="90" y="640" width="330" height="60" as="geometry"/>
<mxCell id="27" value="Who&amp;nbsp; &amp;nbsp; &amp;nbsp;角色&amp;nbsp; &amp;nbsp;Namespace&lt;div&gt;A&amp;nbsp; 开发 项目A&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="110" y="620" width="330" height="60" as="geometry"/>
</mxCell>
<mxCell id="28" value="授权" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxCell id="28" value="授权" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="90" y="610" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="30" style="edgeStyle=none;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="29" target="25">
<mxCell id="30" style="edgeStyle=none;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="29" target="25" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="31" value="1:N&amp;nbsp; 多个权限的集合" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="30">
<mxCell id="31" value="1:N&amp;nbsp; 多个权限的集合" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="30" vertex="1" connectable="0">
<mxGeometry x="0.3254" y="2" relative="1" as="geometry">
<mxPoint x="-30" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="29" value="角色&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="29" value="角色&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="293.5" y="510" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="34" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="34" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="100" y="810" width="790" height="150" as="geometry"/>
</mxCell>
<mxCell id="37" style="html=1;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="35" target="38">
<mxCell id="37" style="html=1;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;" parent="1" source="35" target="38" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="35" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxCell id="35" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
<mxGeometry x="50" y="720" width="30" height="60" as="geometry"/>
</mxCell>
<mxCell id="36" value="资源" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="36" value="资源" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="120" y="890" width="120" height="50" as="geometry"/>
</mxCell>
<mxCell id="39" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="38" target="36">
<mxCell id="39" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="38" target="36" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="41" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="38" target="40">
<mxCell id="41" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="38" target="40" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="38" value="权限拦截器" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="38" value="权限拦截器" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="120" y="830" width="120" height="45" as="geometry"/>
</mxCell>
<mxCell id="40" value="授权策略&lt;div&gt;用户的授权策略&lt;/div&gt;&lt;div&gt;User, Name, 接口&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="40" value="授权策略&lt;div&gt;用户的授权策略&lt;/div&gt;&lt;div&gt;User, Name, 接口&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="294" y="830" width="120" height="50" as="geometry"/>
</mxCell>
<mxCell id="42" value="空间&lt;div&gt;Namepsace&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="460" y="825" width="120" height="50" as="geometry"/>
<mxCell id="42" value="空间&lt;div&gt;Namepsace&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="460" y="830" width="120" height="50" as="geometry"/>
</mxCell>
<mxCell id="43" value="角色&lt;div&gt;Role&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="620" y="825" width="120" height="50" as="geometry"/>
<mxCell id="43" value="角色&lt;div&gt;Role&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="620" y="830" width="120" height="50" as="geometry"/>
</mxCell>
<mxCell id="44" value="接口列表" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxCell id="44" value="接口列表" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="760" y="825" width="120" height="55" as="geometry"/>
</mxCell>
<mxCell id="45" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="100" y="1090" width="330" height="180" as="geometry"/>
</mxCell>
<mxCell id="46" value="用户认证" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="100" y="1060" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="49" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="47" target="48">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="47" value="token" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="280" y="1119" width="120" height="50" as="geometry"/>
</mxCell>
<mxCell id="48" value="user" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="1119" width="120" height="50" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>

View File

@ -0,0 +1,22 @@
<mxfile host="65bd71144e">
<diagram id="poUq6wZcfCQim5LskJLo" name="第 1 页">
<mxGraphModel dx="830" dy="442" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="60" y="40" width="690" height="390" as="geometry"/>
</mxCell>
<mxCell id="3" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="130" y="60" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="280" y="60" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="430" y="60" width="120" height="40" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@ -27,6 +27,8 @@ func (m *MapContainer) Get(name string) Object {
}
// 初始化所有已经注册的对象
// yaml, toml map[key]obj
// [object_name]
func (m *MapContainer) Init() error {
for _, v := range m.storage {
if err := v.Init(); err != nil {