1. 思路

参考:https://stackoverflow.com/questions/20826201/simple-csrf-protection-using-nginx-alone?r=SearchResults

第一步:

前端页面向后端发送生成csrf请求(get 方法),后端服务器生成csrf_token返回gei前端

第二步:

前端收到csrf_token后,将csrf_token写入cookie中,在post请求中,随cookie与请求头发送到后端中。

2.相关代码

2.1 Nginx 配置

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
## # Default server configuration
#
#server {
# listen 80 default_server;
# listen [::]:80 default_server; # SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf; # root /var/www/html; # Add index.php to the list if you are using PHP
# index index.html index.htm index.nginx-debian.html; # server_name _; # location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
# } # pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/run/php/php7.3-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#} # deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
#} # Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
server {
listen 80;
listen [::]:80;
#
server_name localhost;
#
#root /var/www/example.com;
# root /var/www/html; # root /home/pi/Desktop/tornado_example/linux_tornado/movie/static;
# index index.html;
#
location ~* /admin/ {
# try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:5000;
# proxy_connect_timeout 600;
# proxy_read_timeout 600;
proxy_cookie_domain localhost:5000 localhost:80; #保证cookie不受跨域影响
} location / {
root /var/www/;
index index.nginx-debian.html; } location /html/ {
root /var/www/static/;
index index.nginx-debian.html; }
}

2.1 flask 后端编写

from flask_wtf import csrf

@admin.route("/csrf_token")
def get_csrf_token():
"生成csrf_token"
csrf_token = csrf.generate_csrf()
return '{"errno":0,"errmsg":"OK","csrf_token":"%s"}' % csrf_token,200,{"Content-Type":"application/json"}

2.2 前端编写

js 文件

login.js

function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
} function setCookie() { $.get("/admin/csrf_token",function(resp) { // 向后端发送获取csrf_token 请求 $("#csrf_token").attr("csrf_token",resp.csrf_token) // 将得到的 csrf_token写道html元素中
}); } $(document).ready(function() {
$("#user").focus(function(){
$("#user-err").hide();
});
$("#password").focus(function(){
$("#password-err").hide();
}); setCookie() //获取csrf_token $(".form-login").submit(function(e){
e.preventDefault();
account = $("#user").val();
passwd = $("#password").val();
if (!account) {
$("#user-err span").html("请填写正确帐号!");
$("#user-err").show();
return;
}
if (!passwd) {
$("#password-err span").html("请填写密码!");
$("#password-err").show();
return;
}
var data = {
account:account,
password:passwd
}; var csrf_data = $("#csrf_token").attr("csrf_token"); // 从html 获取csrf_token document.cookie = "csrf_token" + "=" + csrf_data; // 将csrf_token 写入cookie var jsonData = JSON.stringify(data);
$.ajax({ // post 请求登录
url:"/admin/sessions",
type:"post",
data:jsonData,
contentType:"application/json",
dataType:"json",
headers:{
"X-CSRFToken":getCookie("csrf_token")
},
success:function (data) {
if (data.errno=="0"){
// 登录成功,跳转到主页
location.href ="/html/index.html"
} else {
// 其他错误信息,在页面中展示
$("#password-err span").html(data.errmsg);
$("#password-err").show();
}
}
});
});
})

html 文件

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>招投标爬虫管理</title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <link rel="stylesheet" href="../static/admin/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="../static/fonts/css/font-awesome.min.css">
<link rel="stylesheet" href="../static/ionicons/css/ionicons.min.css">
<link rel="stylesheet" href="../static/admin/dist/css/AdminLTE.min.css">
<link rel="stylesheet" href="../static/admin/plugins/iCheck/square/blue.css">
</head>
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<a href=""><b>招投标爬虫系统</b></a>
</div>
<div class="login-box-body">
<p class="login-box-msg"></p>
<form class="form-login">
<div class="form-group has-feedback">
<input name="user" id="user" type="text" class="form-control" placeholder="请输入账号!">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
<div class="col-md-12" id="input_user"></div>
</div>
<div class="error-msg" id="user-err"><i class="fa fa-exclamation-circle"></i><span></span></div>
<div class="form-group has-feedback">
<input name="pwd" id="password" type="password" class="form-control" placeholder="请输入密码!">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
<div class="col-md-12" id="input_pwd"></div>
</div>
<div class="error-msg" id="password-err"><i class="fa fa-exclamation-circle"></i><span></span></div>
<div class="form-group has-feedback">
<input name="csrf_token" id="csrf_token" type="hidden" class="form-control" >
</div>
<div class="row">
<div class="col-xs-8"></div>
<div class="col-xs-4">
<input id="btn-sub" type="submit" class="btn btn-primary btn-block btn-flat" value="登录">
</div>
</div>
</form>
</div>
</div>
<script src="../static/admin/plugins/jQuery/jQuery-2.2.0.min.js"></script>
<script src="../static/admin/bootstrap/js/bootstrap.min.js"></script>
<script src="../static/admin/plugins/iCheck/icheck.min.js"></script> <script src="/static/js/crawler/login.js"></script> </body>
</html>

web 部署专题(九):Nginx 前后端分离中csrf_token 认证的实现的更多相关文章

  1. 前后端分离中的无痛刷新token机制

    今天我们来说一说前后端分离中的无痛刷新token机制 博主先来分享一波福利,最近挖到的宝藏,刚开始学Java的同学看 https://www.bilibili.com/video/BV1Rx41187 ...

  2. nodejs--JWT 在前后端分离中的应用与实践

    nodejs--JWT 在前后端分离中的应用与实践 http://www.cnblogs.com/lidongyue/p/5269695.html

  3. Nginx部署前端代码实现前后端分离

    实现前后端分离,可以让前后端独立开发.独立部署.独立单测,双方通过JSON进行数据交互. 对于前端开发人员来说,不用每次调试都需要启动或配置Java/Tomcat运行环境:对于后端开发人员来说 ,也不 ...

  4. 通过nginx部署前端代码实现前后端分离

    实现前后端分离,可以让前后端独立开发.独立部署.独立单测,双方通过JSON进行数据交互. 对于前端开发人员来说,不用每次调试都需要启动或配置Java/Tomcat运行环境:对于后端开发人员来说 ,也不 ...

  5. 谈谈渲染,玩玩nginx——前后端分离,转发请求到Tomcat的尝试

    一.谈谈"渲染" 相信好多人都挺听过"渲染"这个词,但不清楚它是什么意思?前端开发以为这是后端的活儿,后端开发以为是前端的事儿,推着推着就不了了之.其实渲染很简 ...

  6. nginx 前后端分离 代理转发,解决跨域问题

    场景 适用于公司有前端,项目采用前后端分离.类似于我们 后端 springboot 提供接口,前端专门写html调用相应的接口,解决跨域问题 配置说明 worker_processes 1; even ...

  7. JWT 在前后端分离中的应用与实践

    关于前后端分离 前后端分离是一个很有趣的议题,它不仅仅是指前后端工程师之间的相互独立的合作分工方式,更是前后端之间开发模式与交互模式的模块化.解耦化.计算机世界的经验告诉我们,对于复杂的事物,模块化总 ...

  8. 基于前后端分离的身份认证方式——JWT

    什么是JWT JWT--Json web token 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,可实现无状态.分布式的Web应用授权. 现在一般都用redis来出来token做 ...

  9. shiro vue 前后端分离中模拟登录遇到的坑

    系统采用jeeplus框架(ssm+redis+shiro+mongodb+redis),默认是了JSP未做前后端分离,由于业务需要已经多终端使用的需求(H5.小程序等),需要实现前后端分离.但是由于 ...

随机推荐

  1. 如何使用PHP生成图片

    /** * 从图片文件创建Image资源 * @param $file 图片文件,支持url * @return bool|resource 成功返回图片image资源,失败返回false */ fu ...

  2. Java实现定时任务的三种简单方法

    第一种方法: /** * 先定义一个任务每天执行的时间点,再写一个死循环,不断地拿当前时间和事先定义的时间去比对,若到时间则执行任务 */ @Test public void test1() { St ...

  3. (一)DB、DBMS、SQL之间的关系

    一.概念 DB:数据库(database)相当于一个仓库,用于有组织的采存储数据. DBMS:数据库管理系统(database manage system)数据库是通过DBMS来创建和操作,种类很多( ...

  4. 手把手教你学Numpy,这些api不容错过

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Numpy专题的第5篇文章,我们来继续学习Numpy当中一些常用的数学和统计函数. 基本统计方法 在日常的工作当中,我们经常需要通过一 ...

  5. CentOS7.5搭建Kafka2.11-1.1.0集群与简单测试

    一.下载 下载地址: http://kafka.apache.org/downloads.html    我这里下载的是Scala 2.11对应的 kafka_2.11-1.1.0.tgz 二.集群规 ...

  6. c常用函数-strcpy和strncpy

    strcpy和strncpy strcpy在脚本开发中经常用到,例如处理参数等,它的作用是把一个字符串复制到另一个字符串中. strncpy的作用是把一个字符串中的指定长度复制到另一个字符串中,如果指 ...

  7. Mac下安装octave

    1.首先安装Command Line Tool xcode-select --install2.Mac OSX平台下,用神器Homebrew安装 curl -LsSf http://github.co ...

  8. ubuntu启动打开终端快捷键

    ubuntu启动打开终端快捷键 CTRL+ALT+T

  9. debug PostgreSQL 9.6.18 using Eclipse IDE on CentOS7

    目录 debug PostgreSQL 9.6.18 using Eclipse IDE on CentOS7 1.概览 2.建立用户 3.编译postgre 4.启动Eclipse 5.设置环境变量 ...

  10. twaver html5 如何设置节点不可拖动

    解决思路: 1.创建一个不可移动的图层  :  layer 2.设置不可拖动的节点node 的图层为 layer 见代码: var box = new twaver.ElementBox(); var ...