现在,我们来实现用户登录的功能。修改 default.scheme.js ,在适当位置添加如下代码:

"(GET|POST) /signin": {
  "request": {
    "session": checkNotLogin
  }
},
"POST /signin": {
  "request": {
    "body": checkSigninBody
  }
}

function checkSigninBody() {
  var body = this.request.body;
  var flash;
  if (!body || !body.name) {
    flash = {error: '请填写用户名!'};
  }
  else if (!body.password) {
    flash = {error: '请填写密码!'};
  }
  if (flash) {
    this.flash = flash;
    this.redirect('back');
    return false;
  }
  body.name = validator.trim(body.name);
  body.password = md5(validator.trim(body.password));
  return true;
}

前面介绍过 signup 的验证逻辑,这里类似便不再赘述。修改 routes/signin.js,添加如下代码:

var Models = require('../lib/core');
var $User = Models.$User;

exports.get = function* () {
  yield this.render('signin');
};

exports.post = function* () {
  var data = this.request.body;

  var userInfo = yield $User.getUserByName(data.name);
  if (!userInfo || (userInfo.password !== data.password)) {
    this.flash = {error: '用户名或密码错误!'};
    return this.redirect('back');
  }

  this.session.user = {
    name: userInfo.name,
    email: userInfo.email
  };

  this.flash = {success: '登录成功!'};
  this.redirect('/user/' + userInfo.name);
};

当用户登录时,首先通过用户名查找该用户,如果不存在或存在但密码不匹配,则返回 '用户名或密码错误!' 的提示。存在且密码匹配则将用户信息写入 session 并返回 '登录成功!' 的提示。修改 signin.ejs,添加如下代码:

<% include header %>

<div class="container">
  <div class="ui form segment" style="width:400px;margin:60px auto">
    <form method="post">
      <div class="ui left icon input">
        <i class="mail icon"></i>
        <input type="text" placeholder="用户名" name="name">
      </div>
      <br><br>
      <div class="ui left icon input">
        <i class="lock icon"></i>
        <input type="password" placeholder="密码" name="password">
      </div>
      <br><br>
      <input type="submit" class="ui button fluid" value="登录">
    </form>
  </div>
</div>

<% include footer %>

最后,修改 routes/logout.js,添加如下代码:

exports.get = function* () {
  this.session = null;
  this.redirect('back');
};

至此,我们就完成了用户登录与登出的功能,重启下程序试试吧。