前端安全之 防止CSRF攻击

前端方面不仅仅是把数据渲染在页面上而已、前端要做的事情很多
例如关于安全方面的问题就要做好

假设、一个管理系统,当你登陆系统以后、在你不做安全方面工作的化
别人可以通过你的接口来对你的数据进行增删改查、这就是csrf攻击
数据更改了、有可能会对公司造成很大的影响

关于解决这个问题可以参考如下方案 ----这是我的一个项目
后端用的Node的Express框架搭建的 相关步骤我用注释标注了

首先 下载一个插件 这个插件的使用我会在本章最后介绍、或者可以参考jsonwebtoken相关文档

yarn add jsonwebtoken

然后在用户登陆以后,给返回头以用户名设置token、
前端收到后存放在local storage里面

_createJWT(username) {
	//这个函数生成token
    let privateKey = fs.readFileSync(path.resolve(__dirname, "../key/rsa_private_key.pem"));
    return jwt.sign(username, privateKey, { algorithm: "RS256" });      //最后一个参数时加密算法、具体可了解(https://www.npmjs.com/package/jsonwebtoken)

  }

  async login(req, res) {
    let { username, password } = req.body;         //通过body-parser插件获取req.body的内容
    let user = await UserModel.findOne({ username })       //mongoDB查找用户名

    if (!user) {
      res.send({ code: -1, message: "用户不存在" })
      return;
    }
    let rs = this._comparePwd(password, user["password"]);    //这是给密码加密  相信不用我在这里阐述了
    if (rs) {
      //在session会话里面存储用户名
      req.session.username = user["username"];
      
      let token = this._createJWT(user["username"]);     //生成token
      
      res.set("X-ACCESS-TOKEN", token);      // 设置返回头
      
      log.debug(user["username"] + ':登录成功');
      
      res.send({ code: 1, username: user["username"], message: "用户登录成功" })
    } else {
      res.send({ code: -1, message: "用户登录失败" })
    }
  }

前端收到后就可以存在local storage中,当每次发起请求时做一个全局的拦截
先判断token是否合法、再进行操作
我这个项目前端使用的是jQuery、所以有个全局拦截器可以先发送请求

$.ajaxSetup({
      beforeSend(xhr, setting) {
        let token = localStorage.getItem('token');
        xhr.setRequestHeader('x-access-token', token);
      },
      complete(xhr, setting) {
        if (xhr.responseJSON.code === 401) {
          alert(xhr.responseJSON.message)
          router.go('/index')
        }
      }
    })

后端在执行操作时、通过中间件的next可以决定是否执行
先看路由的配置

router.use(auth);     //假如说、我要添加一个职位、先执行这个auth文件---------这个文件就是用来检查用户是否已登陆并且验证token的地方

router.post('/add', uploadfile, PosController.add)

auth.js

const jwt = require('jsonwebtoken');
const path = require('path');
const fs = require('fs');
const log = require('../util/log')

function auth(req, res, next) {
  try {
    let token = req.get('X-ACCESS-TOKEN');

    let publicKey = fs.readFileSync(path.resolve(__dirname, '../key/rsa_public_key.pem'));    //这里使用公钥解密(关于使用可以参考文档或本章最后参考)
    jwt.verify(token, publicKey, function (err, decode) {
      if (err) {
        res.send({ code: 401, message: "非法访问" })
      } else {
        console.log('decode:', decode)
        if (decode === req.session.username) {
          next()
        } else {
          res.send({ code: 401, message: "非法访问" })
        }
      }
    })

  } catch (error) {
    res.send({ code: 401, message: "非法访问" })
    log.error(req.ip, error.message);
  }

}


module.exports = auth;

这样做有什么好处

1、用户在未登陆的条件下、不能看到本公司职位的信息
2、当用户登陆成功、csrf攻击时并没有我对应的token、当然也不能对我的数据进行操作、有效防止了csrf攻击

关于jsonwebtoken的使用

1、可以使用对称加密

let result = jwt.verify(token,"crocess")   //这里crocess可以随便换值

在解密的文件中

function auth(req,res,next){

    try {
        let token = req.get("X-ACCESS-TOKEN")
    let result = jwt.verify(token,"crocess")
    if(result !== req.session.username){
        res.send({code:401,message:"非法访问"})
    }else{
        next()
    }
    } catch (error) {
        res.send({code:401,message:"非法访问"})
    }
}

这是一种简单的加密、容易被第三方软件破解

2、使用非对称加密 不宜破解
1、下载地址Window: http://slproweb.com/products/Win32OpenSSL.html
2、打开cmd,输入 生成私钥的命令 genrsa -out C:\OpenSSL-Win64\create_key/rsa_private_key.pem 1024
3.利用私钥生成公钥: rsa -in C:\OpenSSL-Win64\create_key/rsa_private_key.pem -pubout -out C:\OpenSSL-Win64\create_key/rsa_public_key.pem

使用就像例子使用即可

  let privateKey = fs.readFileSync(path.resolve(__dirname, "../key/rsa_private_key.pem")); //私钥生成
 let publicKey = fs.readFileSync(path.resolve(__dirname, '../key/rsa_public_key.pem'))   //公钥解密

以上就是关于csrf攻击的防范、当然加密算法可以参考相关文档

对于前端
我远没有达到精通
只是一直在路上

发布了10 篇原创文章 · 获赞 14 · 访问量 1731

猜你喜欢

转载自blog.csdn.net/F_efforts/article/details/104481459