实现 JWT 一键支持#8
Conversation
flycash
left a comment
There was a problem hiding this comment.
- 直接在 ginx 下创建一个 jwt 的子包
- 把 handler,auth 和 jwt 的所有内容打包到一个 Manager 里面,比如说 JWTManager,而后所有的方法都定义到这里
- 其中一个方法叫做 MiddlewareBuilder() MiddlewareBuilder {}。这个 MiddlewareBuilder 就是你现在的 JWT Builder。
之前给你们讲的时候,我是为了从 0-1 才拆得那么分散的。而这里我们要给用户提供简单的使用方法,就可以考虑整合到一起。因为如果组件很多的话,用户很难学会怎么使用。
|
|
||
| // NewManager 定义一个 JWTLoginManger | ||
| // allowTokenHeader: 默认使用 authorization 为认证请求头. | ||
| // bearerPrefix: 默认使用 Bearer 拼接 token. |
There was a problem hiding this comment.
这个是规范,是不能改的,所以不需要这个 bearer prefix。
ginx 是一个比较靠近业务端的中间件,所以它的设计理念是简化用户的操作,扩展性反而不是最重要的。
| // NewManager 定义一个 JWTLoginManger | ||
| // allowTokenHeader: 默认使用 authorization 为认证请求头. | ||
| // bearerPrefix: 默认使用 Bearer 拼接 token. | ||
| // claimsCTXKey: 默认使用 claims 为设置到 gin.Context 的key |
There was a problem hiding this comment.
这个你也不需要允许用户修改,而是直接在 Manager 里面提供一个获取 Claims 的方法
| // 如要使用 refresh 功能则需要使用 WithRefreshJWTOptions 添加相关配置. | ||
| // rotateRefreshToken: 默认不轮换刷新令牌. | ||
| // 该配置需要设置 refreshJWTOptions 才有效. | ||
| func NewManager[T any](accessJWTOptions *Options, |
There was a problem hiding this comment.
在 ekit 的 bean/options 里面我提供了一个通用的 Option 设计,你可以直接使用。
|
|
||
| // WithIgnorePaths 设置忽略资源令牌认证的路径. | ||
| // 例如: '/login', '/api/v1/signup'. | ||
| func WithIgnorePaths[T any](paths ...string) ManagerOption[T] { |
There was a problem hiding this comment.
这里你把 ignorePath 做成函数式的,也就是一个方法。而后你提供一个默认的方法,就是要求用户传入静态的忽略的略经。
func WIthIgnorePath(fn func(path string) bool) {
}
func StaticIgnorePath(paths...string) func(path string) bool 这样子的话后续用户如果有一些按照前缀来忽略的,也很容易做到。
There was a problem hiding this comment.
是这样写吗?
func (m *Manager[T]) StaticIgnorePath(paths ...string) func(path string) bool {
s := set.NewMapSet[string](len(paths))
for _, path := range paths {
s.Add(path)
}
m.publicPaths = s
return func(path string) bool {
if m.publicPaths.Exist(path) {
return true
}
return false
}
}使用的时候改成这样?
func (m *Manager[T]) Middleware() gin.HandlerFunc {
return func(ctx *gin.Context) {
// 不需要校验
if m.ignorePaths(ctx.Request.URL.Path) {
return
}
// 做校验
}
}| return &dOpts | ||
| } | ||
|
|
||
| type ManagerOption[T any] interface { |
There was a problem hiding this comment.
没有必要定义这个接口。正常来说我认为别的框架里面的这种设计是过度设计的产物,普通的 Option 模式就够了。
| } | ||
| ctx.Header(m.exposeRefreshHeader, refreshToken) | ||
| } | ||
| ctx.Status(http.StatusOK) |
There was a problem hiding this comment.
换 204 这个响应。就是 NoContent,因为我们都把数据放到各个 Header 里面了
| } | ||
|
|
||
| // MiddlewareBuilder 登录认证的中间件 | ||
| func (m *Manager[T]) MiddlewareBuilder() gin.HandlerFunc { |
There was a problem hiding this comment.
你这里既然是直接返回了一个 gin.HandlerFunc,那么可以把方案名字重命名为 Middleware()。之前我说 MiddlewareBuilder 是希望这里还有一个 MiddlewareBuilder,然后在 MiddlewareBuilder 上设置 IgnorePath 等。我认为这样 Middleware 将来比较好扩展。
|
已根据意见重新修改 |
No description provided.