登录接口必须校验密码哈希、强制验证码、控制会话有效期并重定向,仅Session::set()不安全;需用password_verify()比对、captcha_check()拦截、trim()清理验证码、同域跳转确保Cookie生效。
是登录成功的必要动作,但仅靠它不能构成安全可用的登录接口。必须配合密码校验、防暴力、验证码、会话有效期控制,否则直接暴露
就等于开放后门。
登录接口必须校验密码,不能只查数据库存在性
常见错误是只用
判断用户是否存在,就认为登录成功。这会导致任意用户名(哪怕没设密码)都能“登录”。
必须对明文密码做哈希比对:用
(推荐),或严格比对
(仅限遗留系统,不安全)
数据库字段必须存哈希值,不能存明文;ThinkPHP 6/8 中建议用
生成,而非手写
或
若用模型查询,确保
拿到的是完整记录,包含
字段
验证码不是可选项,而是登录接口的前置拦截点
没加验证码的登录接口,在生产环境基本等于裸奔。ThinkPHP 自带
,但容易踩两个坑:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
返回
时,必须立刻中断流程并返回错误,不能继续查库——否则攻击者可绕过验证码爆破账号
前端传来的
值要 trim(),浏览器输入框可能带空格;后端调用前建议写
验证码配置在
,关键项
和
要显式设好,避免默认值引发兼容问题
Session 写入后必须重定向,不能直接返回 JSON
前后端分离项目常犯的错:登录成功后
,但前端收不到 session cookie。根本原因是 PHP 的 session ID 默认通过 Set-Cookie 响应头下发,而现代浏览器对跨域请求的 cookie 有严格限制。
若前端域名与后端不一致(如
→
),必须开启 CORS 并设置
,且后端响应头加
更稳妥的做法是登录成功后用
跳转到同域首页,由首页接口再拉取用户信息——这样 session cookie 能自然带上
ThinkPHP 8 多应用模式下,
应用的 session 默认隔离,别误用
应用的 session 配置
真正难的不是写通登录,而是让每次登录都不可预测、不可复用、不可绕过。比如
参数漏校验会导致微信登录被 CSRF,
没及时换 token 会让授权失效,验证码图片 URL 缺少时间戳参数会让缓存击中旧图——这些细节不在文档里,但在日志和报错里反复出现。
Session::set()Session::set('user', $data)Db::name('users')->where('username', $username)->find()password_verify($input_pwd, $db_hash)md5($input_pwd)password_hash()md5()sha1()UserModel::where('username', $username)->find()passwordcaptcha_check()captcha_check($vcode)falsevcode$vcode = trim(input('post.vcode'))config/captcha.php'length' => 5'useZh' => falsereturn json(['code'=>0, 'msg'=>'ok'])http://localhost:3000http://localhost:8000'withCredentials' => trueAccess-Control-Allow-Credentials: true$this->redirect('/')adminindexstatecode