ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 创建用户表 利用migration创建一个用户表 ``` php think migrate:create Users ``` ## 编写 migration ``` public function change() { $table = $this->table('users', ['engine' => 'InnoDB']); $table->addColumn('name', 'string',['limit' => 50, 'default'=>'','comment'=>'用户名']) ->addColumn('email', 'string',['limit' => 255, 'default'=>'','comment'=>'邮箱']) ->addColumn('password', 'string',['limit' => 255, 'default'=>'','comment'=>'密码']) ->addColumn('remember_token', 'string',['limit' => 255, 'default'=>'','comment'=>'记住token']) ->addColumn('login_ip', 'string',['limit' => 50, 'default'=>'','comment'=>'登录IP']) ->addColumn('login_at', 'timestamp', [ 'comment' => '最近登录时间']) ->addColumn('created_at', 'timestamp', [ 'comment' => '更新时间']) ->addIndex(['name'], ['unique' => true]) ->create(); } ``` ## 创建用户表 ``` php think migrate:run ``` 以上步骤可以成功创建用户表了 ## 创建User模型 ``` namespace app\model; class UserModel extends AbstractBase { public function store($data) { // TODO: Implement store() method. $this->data($data); return $this->save(); } public function deleteBy($id) { // TODO: Implement deleteBy() method. return $this->where('id', $id)->delete(); } public function updateBy($id, $data) { // TODO: Implement updateBy() method. return $this->where('id', $id)->update($data); } public function findBy($id) { // TODO: Implement findBy() method. return $this->where('id', $id)->findOrEmpty(); } /** * 根据 NAME 查找 * @param $name * @return array|null|\PDOStatement|string|\think\Model */ public function findByName($name, $id = null) { $where = [ 'name' => $name, ]; if ($id) { $where['id'] = ['<>', $id]; return self::where($this->conditions($where))->find(); } return self::where($where)->find(); } /** * 根据 EMAIL 查找 * @param $email * @param null $id * @return array|null|\PDOStatement|string|\think\Model */ public function findByEmail($email, $id = null) { $where = [ 'email' => $email, ]; if ($id) { $where['id'] = ['<>', $id]; return self::where($this->conditions($where))->find(); } return self::where($where)->find(); } } ``` 模型创建成功之后了,下面开始实现登录。 ## 登录的实现 创建 app\traits\Auth.php 认证文件,简化一下实现思路。以及几个功能点。 > 1.必须登录成功 2.需要记住功能 记住的实现,肯定利用到了Cookie,需要对remember_token进行认证便可以了。 下面看一下代码的实现。 ``` namespace app\traits; use think\Request; use think\Validate; use think\facade\Session; use think\facade\Cookie; use app\model\UserModel as User; trait Auth { public function authLogin(Request $request) { $err = $this->validateLogin($request); if ($err) { $this->error($err); } // 正常输入登录 $userModel = new User(); $filed = explode('|', $this->name()); $user = $userModel::where($filed[0], $request->param($filed[0]))->findOrEmpty(); if (!$user) { $this->error('登录失败'); } if (password_verify($request->param('password'), $user->password)) { Session::set('user', $user); // 记住登录 $this->LoginRemember($user, $request); $this->success('登录成功', url($this->redirect)); } $this->error('登录失败'); } /** * 记住登录 * @return bool */ public function rememberLogin() { // 如果记住登录 if (!Session::get('user') && Cookie::get('remember_token') && $this->checkRememberToken()) { return true; } return false; } /** * 退出 * @return void */ public function authLogout() { $user = Session::get('user'); $user->remember_token = null; $user->save(); Cookie::delete('remember_token'); Session::delete('user'); } /** * 验证 * @param Request $request * @return array|bool */ protected function validateLogin(Request $request) { $validate = new Validate($this->rule()); if (!$validate->check($request->except(['remember']))) { return $validate->getError(); } return false; } /** * 登录验证规则 * @return array */ protected function rule() { return [ $this->name() => 'require|token|alphaDash', 'password|密码' => 'require|alphaDash', //'captcha|验证码' => 'require|captcha' ]; } /** * 设置登录字段 * * @return string */ protected function name() { return 'name|用户名'; } /** * Remember Token * * @return string */ public function generateRememberToken() { return uniqid(md5(time()+rand(10000, 99999))); } /** * 加密 TOKEN * * @param $user_id * @param $remember_token * @return string */ protected function secretRememberToken($user_id, $remember_token) { list($key, $method, $iv) = $this->getSecret(); return base64_encode(openssl_encrypt($user_id . ':' . $remember_token, $method, $key, OPENSSL_RAW_DATA, $iv)); } /** * 检查remember token 是否正确 * * @return bool */ protected function checkRememberToken() { if (!Cookie::has('remember_token')) { return false; } $rememberToken = Cookie::get('remember_token'); // 解密 list($key, $method, $iv) = $this->getSecret(); list($userID) = explode(':', (openssl_decrypt(base64_decode($rememberToken), $method, $key, OPENSSL_RAW_DATA, $iv))); // 校验 $user = (new User())->findBy($userID); Session::set('user', $user); return $user->remember_token == $rememberToken; } /** * 加密 * * @return array */ protected function getSecret() { return ['admin_auth', 'AES-128-CBC', '1234567890123412']; } /** * 记住 * * @param $user * @return void */ protected function LoginRemember($user, Request $request) { if ($request->has('remember')) { $rememberToken = $this->secretRememberToken($user->id, $this->generateRememberToken()); $user->remember_token = $rememberToken; Cookie::forever('remember_token', $rememberToken); } $user->login_at = date('Y-m-d h:i:s', time()); $user->login_ip = request()->ip(); $user->save(); } } ``` Auth实现之后登录就很方便了。 ## login 实现 创建 application\admin\controller\Login.php ``` namespace app\admin\controller; use think\Controller; use app\traits\Auth; class Login extends Controller { use Auth; protected $redirect = 'admin/index/index'; /** * Login Page * * @return mixed */ public function login() { // 登录逻辑 if ($this->request->isPost()) { $this->authLogin($this->request); } // 记住登录的话, 直接登录 if ($this->rememberLogin()) { return redirect($this->redirect); } return $this->fetch('admin/login/login'); } /** * 登出 * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\think\response\Redirect */ public function logout() { $this->authLogout(); return redirect('admin/login/login'); } } ``` ## 页面效果