token设计
This commit is contained in:
parent
c176c4086f
commit
cc4729de15
@ -10,3 +10,18 @@
|
|||||||
|
|
||||||
鉴权: 你能干什么(范围)
|
鉴权: 你能干什么(范围)
|
||||||
|
|
||||||
|
|
||||||
|
## 概要设计
|
||||||
|
|
||||||
|
针对问题(需求),给出一种解决方案(解题)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 详细设计
|
||||||
|
|
||||||
|
定义业务
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,2 +1,20 @@
|
|||||||
# 令牌管理
|
# 令牌管理
|
||||||
|
|
||||||
|
+ 颁发访问令牌: Login
|
||||||
|
+ 撤销访问令牌: 令牌失效了 Logout
|
||||||
|
+ 校验访问令牌:检查令牌的合法性, 是不是伪造的
|
||||||
|
|
||||||
|
## 详情设计的时候
|
||||||
|
|
||||||
|
字段(业务需求)
|
||||||
|
|
||||||
|
令牌:
|
||||||
|
+ 过期时间
|
||||||
|
+ 颁发时间
|
||||||
|
+ 被颁发的人
|
||||||
|
+ ...
|
||||||
|
|
||||||
|
|
||||||
|
问题: 无刷新功能, 令牌到期了,自动退出了, 过期时间设置长一点, 长时间不过期 又有安全问题
|
||||||
|
1. 业务功能: 令牌的刷新, 令牌过期了过后,允许用户进行刷新(需要使用刷新Token来刷新, 刷新Token也是需要有过期时间, 这个时间决定回话长度),有了刷新token用户不会出现 使用中被中断的情况, 并且长时间未使用,系统也户自动退出(刷新Token过期)
|
||||||
|
|
||||||
|
0
devcloud/mcenter/apps/token/docs/refresh.drawio
Normal file
0
devcloud/mcenter/apps/token/docs/refresh.drawio
Normal file
31
devcloud/mcenter/apps/token/enum.go
Normal file
31
devcloud/mcenter/apps/token/enum.go
Normal 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
|
||||||
|
)
|
70
devcloud/mcenter/apps/token/interfaceg.go
Normal file
70
devcloud/mcenter/apps/token/interfaceg.go
Normal 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 {
|
||||||
|
}
|
67
devcloud/mcenter/apps/token/model.go
Normal file
67
devcloud/mcenter/apps/token/model.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
13
devcloud/mcenter/apps/token/tools.go
Normal file
13
devcloud/mcenter/apps/token/tools.go
Normal 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
|
||||||
|
}
|
@ -1,144 +1,159 @@
|
|||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="kBUSl4Twz2xUubsumQ87" name="第 1 页">
|
<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>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="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"/>
|
<mxGeometry x="380" y="230" width="330" height="180" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="60" y="230" width="320" height="180" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="60" y="90" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</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">
|
<mxGeometry relative="1" as="geometry">
|
||||||
<mxPoint x="120" y="226" as="targetPoint"/>
|
<mxPoint x="120" y="226" as="targetPoint"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</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">
|
<mxGeometry x="-0.1648" y="6" relative="1" as="geometry">
|
||||||
<mxPoint as="offset"/>
|
<mxPoint as="offset"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="160" y="170" width="180" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</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">
|
<mxGeometry x="-0.0981" y="-3" relative="1" as="geometry">
|
||||||
<mxPoint as="offset"/>
|
<mxPoint as="offset"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="70" y="250" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="250" y="250" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="380" y="90" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</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">
|
<mxGeometry relative="1" as="geometry">
|
||||||
<mxPoint x="440" y="230" as="targetPoint"/>
|
<mxPoint x="440" y="230" as="targetPoint"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="460" y="170" width="180" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="18" value="用自己的身份信息 换一个凭证<div>1. user/pass</div><div>2. 手机登录</div><div>3. 三分认证: 飞书/支付宝</div><div>4. LDAP 凭证</div><div>...</div>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="17">
|
<mxCell id="18" value="用自己的身份信息 换一个凭证<div>1. user/pass</div><div>2. 手机登录</div><div>3. 三分认证: 飞书/支付宝</div><div>4. LDAP 凭证</div><div>...</div>" 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">
|
<mxGeometry x="0.3099" y="-1" relative="1" as="geometry">
|
||||||
<mxPoint as="offset"/>
|
<mxPoint as="offset"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="730" y="60" width="30" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="570" y="250" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="80" y="350" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="390" y="350" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="580" y="350" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="390" y="250" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="25" value="操作<div>具体的接口</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="25" value="操作<div>具体的接口</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="560" y="510" width="120" height="60" as="geometry"/>
|
<mxGeometry x="560" y="510" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="110" y="500" width="30" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="27" value="Who&nbsp; &nbsp; &nbsp;角色&nbsp; &nbsp;Namespace<div>A&nbsp; 开发 项目A</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="27" value="Who&nbsp; &nbsp; &nbsp;角色&nbsp; &nbsp;Namespace<div>A&nbsp; 开发 项目A</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="90" y="640" width="330" height="60" as="geometry"/>
|
<mxGeometry x="110" y="620" width="330" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="90" y="610" width="60" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="31" value="1:N&nbsp; 多个权限的集合" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="30">
|
<mxCell id="31" value="1:N&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">
|
<mxGeometry x="0.3254" y="2" relative="1" as="geometry">
|
||||||
<mxPoint x="-30" as="offset"/>
|
<mxPoint x="-30" as="offset"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="29" value="角色<div><br></div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="29" value="角色<div><br></div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="293.5" y="510" width="120" height="60" as="geometry"/>
|
<mxGeometry x="293.5" y="510" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="100" y="810" width="790" height="150" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="50" y="720" width="30" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="120" y="890" width="120" height="50" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="120" y="830" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="40" value="授权策略<div>用户的授权策略</div><div>User, Name, 接口</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="40" value="授权策略<div>用户的授权策略</div><div>User, Name, 接口</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="294" y="830" width="120" height="50" as="geometry"/>
|
<mxGeometry x="294" y="830" width="120" height="50" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="42" value="空间<div>Namepsace</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="42" value="空间<div>Namepsace</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="460" y="825" width="120" height="50" as="geometry"/>
|
<mxGeometry x="460" y="830" width="120" height="50" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="43" value="角色<div>Role</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="43" value="角色<div>Role</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="620" y="825" width="120" height="50" as="geometry"/>
|
<mxGeometry x="620" y="830" width="120" height="50" as="geometry"/>
|
||||||
</mxCell>
|
</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"/>
|
<mxGeometry x="760" y="825" width="120" height="55" as="geometry"/>
|
||||||
</mxCell>
|
</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>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
|
@ -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>
|
BIN
docs/Go 语言大型项目开发必备技能之Ioc.pptx
Normal file
BIN
docs/Go 语言大型项目开发必备技能之Ioc.pptx
Normal file
Binary file not shown.
@ -27,6 +27,8 @@ func (m *MapContainer) Get(name string) Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 初始化所有已经注册的对象
|
// 初始化所有已经注册的对象
|
||||||
|
// yaml, toml map[key]obj
|
||||||
|
// [object_name]
|
||||||
func (m *MapContainer) Init() error {
|
func (m *MapContainer) Init() error {
|
||||||
for _, v := range m.storage {
|
for _, v := range m.storage {
|
||||||
if err := v.Init(); err != nil {
|
if err := v.Init(); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user