美文网首页
跟我一起学Express之session、redis、登录验证

跟我一起学Express之session、redis、登录验证

作者: 喜剧之王爱创作 | 来源:发表于2020-05-10 21:40 被阅读0次

    上节我们说到,express中间件,并简单实现了我们自己的中间件,按照小编自己的理解

    express就是靠中间件为我们提供了众多通用功能

    然后,我们就在我们之前搭建的express项目中进行二次开发吧!

    初始化项目

    首先,我们将我们之前原生项目中的一个工具函数,数据库配置等拷贝到我们的express项目根目录下,按照之前的文件结构。其中保包括

    • controller文件夹
    • db文件夹(数据库连接)
    • conf文件夹(数据库,redis环境配置)
    • untils工具文件夹(包括密码加密等)
    • model文件夹(数据模型)

    然后我们在我们的router下的list接口中做个示范,其他接口同理

    router.get('/list', function (req, res, next) {
      let author = req.query.author || ''
      const keyword = req.query.keyword || ''
      // if (req.query.isadmin) {
      //   const loginCheckResult = loginCheck(req)
      //   if (loginCheckResult) {
      //     return loginCheckResult
      //   }
      //   // 强制查询自己的博客
      //   author = req.session.username
      // }
      const result = getList(author, keyword)
      return result.then(listData => {
        res.json(
          new SuccessModel(listData)
        )
      })
    });
    

    我只需要使用res.json就可以返回对应数据。我们也可以直接从req.query中拿到参数,不用手动注入。其他的没有变化,这里的登录验证,我们先注掉,回头再加上。好了,快打开你的浏览器试一下通了没有。

    处理session

    在express中,我们无需再自己处理session,我们将使用一个叫express-session的插件。下面我们先安装他,再看怎么去使用

    yarn add express-session -S
    

    我们这样去使用它

    app.use(session({
      secret: 'HUHS_35446#',//session密匙
      cookie: {
        path: '/', // 默认配置
        httpOnly: true, // 默认配置
        maxAge: 24 * 60 * 60 * 1000
      }
    }))
    

    我们使用中间件的形式对其进行使用。这里需要注意我们要在路由之前处理session
    现在去刷新浏览器,看是不是浏览器的cookie中多了一个值呢?下面我们将去测试其可用。
    在user路由里新建一个测试的路由,如下

    router.get('/session-test', function(req, res, next) {
        const session = req.session
        if(session.viewNum == null) {
            session.viewNum = 0
        }
        session.viewNum ++
      res.json({
        viewNum: session.viewNum
      })
    });
    

    打开你的浏览器测试一下吧!看看有没有将我们自定义的变量存入到session中呢?

    登录

    和之前原生一样,我们依然是处理session。并且代码逻辑几乎一样

    const { username, password } = req.body
    const result = login(username, password)
    return result.then(data => {
        if (data.username) {
            // 设置session
            req.session.username = data.username
            req.session.realname = data.realname
            res.json(
                new SuccessModel()
            )
            return
        }
        res.json(
            new ErrorModel('登陆失败')
        )
    })
    

    注意,这里我们并没有去同步redis因为我们使用的框架将自动帮我们同步redis。接下来就看看我们如何使用框架连接redis吧!

    连接redis

    这里我们省去了像原生那样的封装工具函数,连接函数等,直接使用两个工具redisconnect-redis

    yarn add redis connect-redis -S
    

    下面我们使用这两个工具,连接redis
    首先我们创建db/redis.js来创建导出一个redis连接对象如下:

    const redis = require('redis')
    
    const { REDIS_CONF } = require('../conf/db')
    
    // 创建客户端
    
    const redisClient = redis.createClient(REDIS_CONF.port, REDIS_CONF.host)
    
    redisClient.on('error', err => {
        console.log(err)
    })
    
    module.exports = redisClient
    

    这一点和原生没有太大区别,只是去掉了原来的set和get函数。

    接下来,需要在入口里面将其配置连接

    const session = require('express-session')
    const RedisStore = require('connect-redis')(session)
    
    
    const redisClient = require('./db/redis')
    const sessionStore = new RedisStore({
      client: redisClient
    })
    
    
    app.use(session({
      secret: 'HUHS_35446#',
      cookie: {
        path: '/', // 默认配置
        httpOnly: true, // 默认配置
        maxAge: 24 * 60 * 60 * 1000
      },
      store: sessionStore
    }))
    

    只需要做如上面的配置就可以轻松的实现redis的连接和数据管理,试一下吧!

    登录中间件

    为了实现登录验证,我们需要实现一个登录验证的中间件,在项目中新建middleware/loginCheck.js

    const { ErrorModel } = require('../model/resModel')
    
    module.exports = (req, res, next) => {
        if(req.session.username) {
            next()
            return
        }
        res.json(new ErrorModel('未登录'))
    }
    

    是不是很简单的,符合我们之前描述的中间件的写法,其本质就是一个函数,下面我们将其使用即可,如下

    router.post('/new', loginCheck, function (req, res, next) {}
    

    对于那些接口不是全部需要登录验证的路由来说,我们就不必像上面那样直接使用中间件了,下面我们完成之前的博客列表管理员页面的验证

      if (req.query.isadmin) {
        if (req.session.username == null) {
          res.json(
            new ErrorModel('未登录')
          )
          return
        }
        // 强制查询自己的博客
        author = req.session.username
      }
    

    对,这里不需要像‘新建’那样直接使用中间件,因为新建时始终需要做登录验证的,而我们的列表页面,只有管理员页面才需要登录验证,所以这里就不能使用中间件了做统一拦截了(我感觉这里我描述的比较啰嗦,总之就是不要乱用中间件!看情况使用)

    这样我们就可以在有需要的地方这样使用了!

    写在最后

    到这里,我们已经学会了使用express完成各种接口相关的操作。接下来,就去完善其他的接口吧!试一试

    相关文章

      网友评论

          本文标题:跟我一起学Express之session、redis、登录验证

          本文链接:https://www.haomeiwen.com/subject/zzbsnhtx.html