继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

NodeJS的CSRF跨域访问攻击的解决方案

加菲2代
关注TA
已关注
手记 1
粉丝 1
获赞 8

CSRF跨域访问攻击是什么呢?

一个网页通常会通过POST/PUT/DELETE请求更改对应用户账户的信息。但是浏览器并不会限制其它网站对你网站的访问。如果在其它网站中有一个链接叫“抽奖”,用户点了,该链接正是调用你网站的支付接口,那么用户就会莫名奇妙的损失了钱财。

CSRF的解决方案是什么呢?

关键是保证后端只能接受自己的前端放送过来的POST/PUT/DELET这些增删改的接口。为什么不屏蔽GET呢。嘿嘿,当然我们需要通过别的网站的链接也能访问到自己的网站啦。屏蔽了外网站的GET也就屏蔽了网站外链接,那么用户也没发通过搜索或者导航网站网站了呀,得不偿失。

如果保证呢后端只接受本网站前端发出的请求呢?

其中一个有效的策略就是由后端生成一个随即字符串,保存在session,我们根据用途给这个随即字符串起个名字叫csrf_token。并在用户第一个访问网页的时候,保存在HTML/JS中,以后前端发送POST/PUT/DELETE的时候,都要加上csrf_token,否则后端接口会拒绝响应,抛出异常。

上代码

后端NodeJS中生成csrf_token随即字符串:

  • 1.后端NodeJS安装csurf包和ejs包
npm install csurf --save
npm install ejs --save
  • 2.后端NodeJS中使用csurf生成csrf_token, 使用ejs在index.html注入token

在NodeJS的入口文件中加入下面的代码

var csrf = require('csurf');
//指定ejs模版文件的名字仍然为.html
//请求过来,仍然默认返回index.html,nodejs可以往index.html写变量拉
app.engine('.html', require('ejs').__express);
app.set('views', path.resolve(publicDir));
app.set('view engine', 'html');

var csrfProtection = csrf({ cookie: true });
app.get(appPath, csrfProtection,  function (req, res){
  // 把生成的csrfToken写入到index.html中去
  res.render('index', { csrfToken: req.csrfToken() })
});

index.html

<!doctype html>
<html class="bootstrap3 legacyfalse chrometwo">
  <head>
    <meta content="<%= csrfToken %>" name="csrf-token">
...
  • 3.前端发送POST中加入csrf_token

在前端中取出csrf_token的值,我是在angular中,利用jQuery取值

$scope.csrfToken = $('meta[name=csrf-token]').attr('content');

在表单请求中加入csrf_token

<form method="post" action="/changevalue" class="ng-pristine ng-valid">
   <input value="value" name="input1">
   <input value="value2" name="input2">
   <input type="hidden" value="{{ csrfToken }}" name="_csrf">
   <button type="submit">submit</button>
</form>
  • 4.在后端NodeJS接口中验证csrf_token
app.post("changevalue" , parseForm, csrfProtection, function (req, res) {   
    res.send("response");
});

完毕!

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP