Beego中登录请求通过POST /login路由触发,控制器需继承beego.Controller并重写Post()方法处理表单;Get()仅用于渲染登录页,密码校验须用bcrypt.CompareHashAndPassword,登录成功调用this.SetSession("uid", user.Id)并this.Redirect("/dashboard", 302),鉴权需在Prepare()中检查session并显式this.Abort("401")或return。

Beego 中如何处理登录请求的路由和控制器
Beego 默认用 POST /login 这类路径接收登录表单,控制器需继承 beego.Controller 并重写 Post() 方法。别直接在 Get() 里写验证逻辑——那是展示登录页的,提交才走 Post()。
常见错误是把用户名密码校验写在 Get() 里,结果刷新页面就触发一次登录失败;或者漏掉 this.Ctx.Input.RequestBody 解析,直接读 this.GetString("username") 却没设 EnableXSRF = false 或配好 XSRF token,导致始终拿不到参数。
- 表单必须用
POST提交,Content-Type推荐application/x-www-form-urlencoded - 若用 JSON 提交,需手动调用
this.ParseForm(&loginForm)或json.Unmarshal(this.Ctx.Input.RequestBody, &loginForm) - Beego 1.12+ 默认开启 XSRF,前端没传
_xsrf字段会返回 403,临时调试可设EnableXSRF = false,上线前务必关掉
如何安全地比对用户密码(别硬编码、别明文存)
Beego 本身不提供密码哈希工具,得自己集成 golang.org/x/crypto/bcrypt。千万别用 == 直接比对明文密码,也别用 md5 或 sha1——这些算法太快,容易被暴力破解。
典型错误是把用户输入的密码 bcrypt.GenerateFromPassword 后再跟数据库存的哈希比——这相当于每次登录都重新哈希,结果永远不等。正确做法是用 bcrypt.CompareHashAndPassword。
- 注册时:用
bcrypt.GenerateFromPassword([]byte(rawPass), bcrypt.DefaultCost)存哈希值到 DB - 登录时:查出用户记录后,用
bcrypt.CompareHashAndPassword([]byte(storedHash), []byte(inputPass)) - 注意
CompareHashAndPassword第一个参数是数据库取回的完整哈希字符串(含 salt 和 cost),不是只取 hash 部分
登录成功后怎么设 session 并跳转
Beego 内置 session 支持,默认用 file 存储,登录成功后调用 this.SetSession("uid", user.Id) 即可。但很多人卡在跳转后 this.GetSession("uid") 返回 nil——大概率是没开 session,或浏览器禁用了 cookie,或反向代理没透传 Set-Cookie 头。
- 确认
session.On = true在conf/app.conf里已启用 - 检查响应头是否有
Set-Cookie: beegosessionID=xxx,没有就说明 session 没生效 - 如果部署在 Nginx 后,确保配置了
proxy_cookie_path / "/";和proxy_pass_request_headers on; - 跳转用
this.Redirect("/dashboard", 302),别用http.Redirect,否则 Beego 的 session 写入会丢失
如何限制未登录用户访问后台接口
Beego 没有全局中间件概念,得靠控制器基类或每个 Prepare() 方法拦截。最稳妥的是写个 BaseController,所有需要鉴权的 controller 继承它,并在 Prepare() 里检查 this.GetSession("uid")。
容易忽略的是:Prepare() 在 Get()/Post() 前执行,但如果用户没登录又没重定向,后续方法仍会执行——必须显式调用 this.Abort("401") 或 this.Redirect("/login", 302) 并 return,否则控制流继续往下跑。
- 不要只写
if uid == nil { this.Redirect(...) }而不加return,Go 不会自动终止方法执行 - 静态资源(如
/static/)、登录页、API 错误页应放行,可在Prepare()里用this.Ctx.Input.URL或this.ControllerName做白名单判断 - REST API 场景建议返回 JSON 错误(
this.Data["json"] = map[string]interface{}{"code": 401, "msg": "unauthorized"}),然后this.ServeJSON(),别跳转
Beego 的登录链路看着简单,但 session 生效条件、XSRF 开关、bcrypt 参数顺序、Prepare 中的 return 缺失——这几个点漏一个,就卡半天。











