Open kingway126 opened 3 years ago
最近我也在魔改这个框架。准备把它接入到公司已有的账户体系,发现这是绝对是一个bug。
目前比较简单的绕过方法是,在数据创建一个叫unknow(叫啥都行)的用户,给一个最小权限。在中间件中,自动用这个用户登录。这样不用伤筋动骨。
因为对项目了解不深,还没想好怎么改。
而且,这个项目在维护吗?
原因: 在HTMLFile方法中,会创建一个handler。无论要不要登录,都调用
var (
tmpl, tmplName = template.Default().GetTemplate(ctx.IsPjax())
user = auth.Auth(ctx) // 既然没登录,auth它干嘛呢?
buf = new(bytes.Buffer)
)
modules/auth/auth.go里面,简单粗暴
func Auth(ctx *context.Context) models.UserModel {
return ctx.User().(models.UserModel)
}
既然没登录,ctx.User()肯定是nil呀。所以挂了。
@dalianzhu 多谢提供解决思路
研究了一下他的用户机制。最核心的在于,他把用户的登录session存在表里。每次登录,会在库里创建这个:
select * from goadmin_session;
+-----+--------------------------------------+---------------+---------------------+---------------------+
| id | sid | values | created_at | updated_at |
+-----+--------------------------------------+---------------+---------------------+---------------------+
| 634 | 222322d5-6724-447c-9718-8fca6194492c | {"user_id":4} | 2020-12-04 07:32:07 | 2020-12-04 07:32:07 |
sid是随机码,values对应里面的一个用户。也就是说,只要伪造一个session,就能绕过登录。下面就是大显身手的时候啦。
因为goadmin没有提供中间件的写法,所以只能依赖框架的中间件,这里我用的是beego。其它的原理类似,在网络框架中写一个全局filter,运行在所有handler之前。 注意,必须先去go admin创建一个账户,账户信息如代码定义,name=unknow, id是4
app.Handlers.InsertFilter("*", beego.BeforeExec, func(ctx *context.Context) {
unknownName := "unknown"
unknownPassword := "unknown"
unknownID := 4
sessionCookieName := "go_admin_session"
sessionStr := ctx.GetCookie(sessionCookieName)
if sessionStr == "" {
// 代表没有cookie,使用Unknow登录
_, ok := auth.Check(unknownName, unknownPassword, conn)
if !ok {
ctx.Redirect(302, "/subadmin/login")
}
// 直接暴力插入一条session记录
tSession := db.WithDriver(models.GetConn()).Table("goadmin_session")
sid := modules.Uuid()
tSession.Insert(dialect.H{
"values": fmt.Sprintf(`{"user_id":%v}`, unknownID),
"sid": sid,
})
// 把cookie设好,跳转,完美
ctx.SetCookie("go_admin_session", sid, 3600, "/")
ctx.Redirect(302, "/subadmin/admin")
}
})
完美。
问题描述 [详细地描述问题,让大家都能理解]
示例代码 [如果有必要,展示代码,线上示例,或仓库]
hello.tmpl
复现方法
版本信息:
其他信息[如截图等其他信息可以贴在这里]
具体报错如下: