# Typecho如何不改核心代码实现自定义登录、注册功能

*Published:* 2023-12-27
*Author:* 客服001

#### 温馨提醒

如果文章内容或图片资源失效，请留言反馈，我们会及时处理，谢谢

本文最后更新于2023年12月27日，已超过 180天没有更新



登录界面咱们需要的就是一个表单，最少提交两个参数：name和password，至于remember则是记住我的功能，需不需要自己决定。

```
<form action="" method="post">
<input type="hidden" name="_" value="<?php echo $this->security->getToken($this->request->getRequestUrl());?>">
用户名：<input type="text" name="name">
密码：<input type="password" name="password">
<input type="submit" value="提交">
</form>
```

这里只是一个最基本的表单功能，要如何美化则靠自己啦，其中\_这个参数是表单安全验证所用。

表单写好了，那提交到哪里呢？这里要看自己的需求，因为原版的登录过后，如果没有referer参数，则会跳转到后台，若您更改了后台路径，并且不想让别人知道，那就只能自己编写一个登录动作，然后提交到这里，如果不在意，则直接提交到原版登录动作就行！

要保护后台路径，那么直接在这个文件中编写代码：

```
// 已登录或不开启注册则跳转首页
if ( $this->user->hasLogin() ) $this->response->redirect($this->options->siteUrl);
// 如果有请求
if ( $this->request->isPost() ) {
  // 验证表单
  $this->security->protect();
  // 如果已经登录
  if ( $this->user->hasLogin() ) $this->response->redirect($this->options->siteUrl);
  // 初始化验证类
  $validator = new <a class="tag_link" href="https://www.xarjtc.com/tag/typecho" target="_blank" title="查看Typecho此标签更多文章"><abbr title="">Typecho</abbr></a>_Validate();
  $validator->addRule('name', 'required', _t('请输入用户名'));
  $validator->addRule('password', 'required', _t('请输入密码'));
  // 验证失败
  if ( $error = $validator->run($this->request->from('name', 'password')) )
     $this->response->redirect($this->options->siteUrl);
  // 验证用户
  $valid = $this->user->login($this->request->name, $this->request->password, false);
  // 验证成功
  if ( $valid ) $this->response->redirect($this->options->siteUrl);
  // 防止穷举, 休眠3秒
  sleep(3);
  // 失败跳转
   $this->response->redirect($this->options->siteUrl);
}
```

而注册页面也同样，建立一个表单，包含几个参数：name、mail、password、confirm，官方不支持自己输入密码，这里把password和confirm加入就能实现自定义密码了！

同样的，如果需要编写动作代码，则把官方的copy一份，不过其中有一点点小改动。

```
if ( $this->request->isPost() ) {
    // 表单验证
    $this->security->protect();
    // 如果已登录或未开启注册
    if ( $this->user->hasLogin() || !$this->options->allowRegister ) $this->response->redirect($this->options->siteUrl);
    // 初始化验证类
    $validator = new Typecho_Validate();
        // 加上这行, 初始化一个Users
    $user = $this->widget('Widget_Abstract_Users');
    $validator->addRule('name', 'required', _t('必须填写用户名称'));
    $validator->addRule('name', 'minLength', _t('用户名至少包含2个字符'), 2);
    $validator->addRule('name', 'maxLength', _t('用户名最多包含32个字符'), 32);
    $validator->addRule('name', 'xssCheck', _t('请不要在用户名中使用特殊字符'));
        // 这里有改动, 使用$this是无法调用的
    $validator->addRule('name', array($user, 'nameExists'), _t('用户名已经存在'));
    $validator->addRule('mail', 'required', _t('必须填写电子邮箱'));
        // 这里同上
    $validator->addRule('mail', array($user, 'mailExists'), _t('电子邮箱地址已经存在'));
    $validator->addRule('mail', 'email', _t('电子邮箱格式错误'));
    $validator->addRule('mail', 'maxLength', _t('电子邮箱最多包含200个字符'), 200);
    $validator->addRule('password', 'required', _t('必须填写密码'));
    $validator->addRule('password', 'minLength', _t('为了保证账户安全, 请输入至少八位的密码'), 8);
    $validator->addRule('password', 'maxLength', _t('为了便于记忆, 密码长度请不要超过十八位'), 18);
    $validator->addRule('confirm', 'confirm', _t('两次输入的密码不一致'), 'password');
    // 验证失败
    if ( $error = $validator->run($this->request->from('name', 'password', 'mail', 'confirm')) )
        $this->response->redirect($this->options->siteUrl);
    $hasher = new PasswordHash(8, true);
        // 由于是自定义密码, 所以这行可以注释了
        // $generatedPassword = Typecho_Common::randString(7);
    $dataStruct = array(
        'name' => $this->request->name,
        'mail' => $this->request->mail,
        'screenName' => $this->request->name,
                // 直接获取提交的密码并加密
        'password' => $hasher->HashPassword($this->request->password),
        'created' => $this->options->time,
        'group' => 'subscriber'
    );
        // 初始化一个Register
    $register = $this->widget('Widget_Register');
        // 插入用户数据
    $insertId = $register->insert($dataStruct);
        // 压入堆栈
    $register->db->fetchRow($register->select()->where('uid = ?', $insertId)->limit(1), array($register, 'push'));
        // 登录
    $this->user->login($this->request->name, $this->request->password);
    $this->response->redirect($this->options->siteUrl);
}
```

把这两个文件扔到主题目录里，然后后台新建两个独立页面，再把登录、注册的链接更改为这两个独立页面地址。