Nodejs + express + sql 学习记录(二)

118 阅读2分钟

1.登录功能的实现

1. 路由部分

  • 在 routes 文件夹里创建用户路由 user.js
  • user.js 里写入login对应的api
var express = require('express');
var router = express.Router();
const { login } = require('../controller/user')
const { SuccessModel, ErrorModel } = require('../model/resModel');

router.post('/login', function(req, res, next) {
  const { username, password } = req.body
  const result = login(username, password)
  return result.then((data) => {
    if(data.username){
      req.session.username = data.username
      req.session.realname = data.realname
      // set(req.sessionID, req.session)
      res.json(
        new SuccessModel()
      )
      return
    }
    res.json(
      new ErrorModel('login failed!')
    ) 
  })
});

2. 数据库部分

controller 文件夹里创建 user.js(对应数据库逻辑)

const { exec, escape } = require('../db/mysql')
const login = (username, password) => {
  username = escape(username)
  password = escape(password)
  const sql = `
  select username, realname from users where username='${username}'
  and password='${password}';
  `;
  return exec(sql).then(rows => {
    return rows[0] || {}
  })
}
module.exports = {
 login
};

3. app.js 里注册路由

const userRouter = require('./routes/user');
app.use('/api/user', userRouter);

2. Session 的实现

1. session 工作原理

1. 用户提交包含用户名和密码的表单,发送HTTP请求
2. 服务器验证用户发来的用户名密码
3. 如果正确则把当前用户名(通常是用户对象)存储到redis中,并生成它在redis中的ID
   这个ID称为Session ID,通过Session ID可以从Redis中取出对应的用户对象, 敏感数据(比如authed=true)都存储在这个用户对象中
4. 设置Cookie为sessionId=xxxxxx|checksum并发送HTTP响应, 仍然为每一项Cookie都设置签名
5. 用户收到HTTP响应后,便看不到任何敏感数据了。在此后的请求中发送该Cookie给服务器
6. 服务器收到此后的HTTP请求后,发现Cookie中有SessionID,进行放篡改验证
7. 如果通过了验证,根据该ID从Redis中取出对应的用户对象, 查看该对象的状态并继续执行业务逻辑。
参考自: https://blog.51cto.com/u_15127576/2668159

2. 安装 express-session

npm install express-session --save

3. app.js里注册session

const session = require('express-session')
// 下面要在路由router之前注册
app.use(session({
    secret: 'abcdef', //类似密匙
    cookie:{
      // 默认配置
      // path: '/',
      // httpOnly: true,
      maxAge: 24 * 60 * 60 * 1000
    },
    resave: true,
    saveUninitialized: true
}))

3. 用户登录验证

  • routes 里面设置登录和登录验证
  • 登录的时候保存username / realname到session里面
  • 登录验证的时候检查是否能在session里取到username的值
var express = require('express');
var router = express.Router();

const { login } = require('../controller/user')
const { SuccessModel, ErrorModel } = require('../utils/resModel')


router.post('/login', function(req, res, next) {
  const { username, password } = req.body
  const result = login(username, password)
  return result.then((data) => {
    if(data.username){
      req.session.username = data.username
      req.session.realname = data.realname
      // set(req.sessionID, req.session)
      res.json(
        new SuccessModel()
      )
      return
    }
    res.json(
      new ErrorModel('login failed!')
    ) 
  })
});

router.get('/login-test', (req, res, next) => {
  console.log(req.session.username);
  if(req.session.username){
    res.json({
      error: 0
    })
    return
  }
  res.json({
    error: -1
  })
})

module.exports = router;