阅读 630

Nodejs之express用户登录的2种方法

本文记录了nodejs中通过session和token如何实现用户登录

首先使用express搭一个服务

express 中间件

  • 中间件能干什么?连接
    1. 执行任何代码。
    2. 修改请求和响应对象。
    3. 终结请求-响应循环。
    4. 调用堆栈中的下一个中间件。
  • 我们需要知道任何一个接口访问服务器的时候对应用户状态,这里需要一个统一的处理,中间件可以帮我们做这些事情
  • 我们自定义一个中间件,它负责检测每一个接口请求服务器的时候对应用户状态。
路径 /middleware/auth.js
const auth = (req, res, next) => {
  /**
   * 这里做一些逻辑判断,可能是校验session_id或者token,下面会说到
   * 校验通过正常放行或者响应数据
   * 校验不通过则直接返回错误信息
   * */ 
  if (true) {
    next();
  } else {
    res.render('fail', { message: '请先登录!' })
  }
}
复制代码
  • 那么我们如何使用这个中间件呢?
路径 /routers/user.js
// 引入刚才自定义好的中间件
var { auth } = require('../middleware/auth');
// 在你希望校验用户信息的接口中使用该中间件,如下:
/* 编辑用户 */
router.post('/edit', auth, userCtl.editUser);
// 不需要校验的接口则无需使用
/* 用户登录 */
router.post('/signIn', userCtl.signIn);
复制代码
  • Ok,我们完成了校验用户状态的流程,现在要说一下基于session和token都如何实现呢?

session实现方法

流程

  1. 用户登录,用户信息校验通过后服务器会存储必要的用户信息到session或redis中,并且生成一个id,这里叫它session_id,通过session_id可以获取用户信息。
  2. 种cookie,设置Cookie为sessionId=xxxxxx|checksum并发送HTTP响应, 仍然为每一项Cookie都设置签名,cookie是携带在http请求中的,后续请求校验cookie中有没有对应sessionId即可判断用户登录状态。

做法

  1. 使用 cookie-session第三方包

    • npm install cookie-session下载依赖
     ```js
     路径 /app.js
     var cookieSession = require('cookie-session');
     
     app.use(cookieSession({
       name: 'session', 
       keys: ['key1', 'key2']
     }))
     ```
    复制代码
  2. 当用户登录成功的时候

路径 controllers/user.js
// 用户信息校验通过
 req.session.username = name; //我这里保存了一个用户名称在cookie中
复制代码
  1. 如何校验?

这里就要用到我们自定义好的中间件了

路径 /middleware/auth.js
const auth = (req, res, next) => {
  const userName = req.session.username;
  if (userName) {
    next();
  } else {
    res.render('fail', { message: '请先登录!' })
  }
}
复制代码

token实现方法

流程

  1. 用户登录,用户信息校验通过后服务通过jwt将必要的用户信息加密,生成一串密文,这里称为token并将token返回前端。
  2. 后续接口请求服务器用户用jwt校验token是否正常来判断用户的状态。
  3. 使用 jsonwebtoken第三方包
    • npm install jsonwebtoken下载依赖
    • 对称加密用法
    路径 controllers/user.js
    // 用户信息校验通过
     var token = jwt.sign({ password: password }, 'afeng666');
     res.render('success', { data: JSON.stringify({ token }), message: '登录成功' })
    复制代码
    • 对称加密校验
        路径 /middleware/auth.js
        const auth = (req, res, next) => {
        let token = req.get('x-token');
         // 捕获解密是否正常
          try {
            var decoded = jwt.verify(token, 'afeng666');
            next();
          } catch (error) {
            res.render('fail', { message: '请先登录!' });
          }
        }
    复制代码
    • 非对称加密用法(比对称加密更安全)
    1. 需要下载Openssl生成公钥和私钥
    2. 贴个下载地址
    3. openssl安装完成后在openssl/bin目录下执行如下命令,当然你也可以配置成全局命令。
     生成公钥: openssl genrsa -out rsa_private_key.pem 1024 
     生成私钥: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
    复制代码
    1. 然后将对应两个文件放到你的文件中。
    2. 用户信息校验通过后使用私钥加密。
    路径 controllers/user.js
        // 用户信息校验通过
     const privateKey = fs.readFileSync(path.join(__dirname , '../rsa/rsa_private_key.pem'));
     //非对称加密指定加密方法
     const token = jwt.sign({ password: password }, privateKey , { algorithm: 'RS256'});
     res.render('success', { data: JSON.stringify({ token }), message: '登录成功' })
    复制代码
    6.使用公钥解密对比
      路径 /middleware/auth.js
      const auth = (req, res, next) => {
        let token = req.get('x-token');
        const publicKey = fs.readFileSync(path.join(__dirname, '../rsa/rsa_public_key.pem'));
       // 捕获解密是否正常
        try {
          const result = jwt.verify(token, publicKey);
          next();
        } catch (error) {
          res.render('fail', { message: '请先登录!' });
        }
      }
复制代码

以上

文章分类
前端
文章标签