Flask-WTForms提供CSRF保护.使用普通HTML表单时效果很好,但使用AJAX时过程不太清楚.我的表单中有文件上传,我用AJAX将进程分成两部分:文件进入upload端点,而表单的其余部分进入submit端点.由于文件是使用AJAX发布的,因此它不会获得CSRF令牌,但我希望保护upload端点免受攻击.如何在使用AJAX时生成CSRF令牌?
@app.route('/submit', methods=["GET","POST"])
@login_required
def submit():
form = MyForm()
if request.method == "POST" and form.validate():
# success, csrf checks out and data is validated
# do stuff
csrf_for_uploads = # generate csrf?
return render_template('some_form.html', form=form, csrf_for_uploads=csrf_for_uploads)
@app.route('/upload', methods=["POST"])
@login_required
def upload():
myfile = request.files['file']
# How do I verify CSRF now?
Run Code Online (Sandbox Code Playgroud) Flask-login doc说我们应该在下次使用时验证next_is_valid(),但我找不到任何这样的方法:
警告:您必须验证下一个参数的值.如果不这样做,您的应用程序将容易受到开放重定向的影响.
@app.route('/login', methods=['GET', 'POST'])
def login():
# Here we use a class of some kind to represent and validate our
# client-side form data. For example, WTForms is a library that will
# handle this for us.
form = LoginForm()
if form.validate_on_submit():
# Login and validate the user.
login_user(user)
flask.flash('Logged in successfully.')
next = flask.request.args.get('next')
if not next_is_valid(next):
return flask.abort(400)
return flask.redirect(next or flask.url_for('index'))
return flask.render_template('login.html', form=form)
Run Code Online (Sandbox Code Playgroud)
运行这个我得到错误:
NameError: global name 'next_is_valid' is not defined …Run Code Online (Sandbox Code Playgroud) 我一直在寻找bunyan登录我的nodejs应用程序.我试了一下,一切似乎都很好.我已经跳过了一节的log.child,但现在我想了解如何使用它.我认为它的目的是允许我为日志条目指定一些特殊标识符,以便我可以唯一地标识该日志与其他日志条目的关联方式.
如果是这种情况,我会设想自己log.child在每个请求中使用:
var bunyan = require('bunyan');
var log = bunyan.createLogger({name: 'myapp'});
router.post('/submit', function(req, res) {
var logChild = log.child({reqId: uuid.v4()});
logChild.info({ req:req }, req.user.name + ' has called /submit');
saveData(req)
.then(function(data) {
logChild.info({data: data}, req.user.name + ' has saved to DB successfully in /submit');
res.json({'success': 'Saved!'});
})
.error(function(err) {
logChild.error({ err: err }, req.user.name + ' has caused an error in /submit ');
res.status(500).json("error": err});
});
});
Run Code Online (Sandbox Code Playgroud)
这样,如果用户在30秒范围内BobPOST /submit两次,则会有一些上下文区分日志文件中的两个不同调用. …
当我缩小我的CSS时,我从各种库中找到了不正确的字体路径.所以,我创建了一个任务来将字体从我的bower_components/文件夹移动到dist/public/fonts:
gulp.task('doit', function() {
gulp.src(["public/bower_components/bootstrap/dist/fonts/*", "public/bower_components/font-awesome/fonts/*"])
.pipe(gulp.dest("dist/public/fonts"));
});
Run Code Online (Sandbox Code Playgroud)
基本上应该把我需要的任何字体扔进一个通用的字体文件夹,我的缩小的CSS现在应该可以访问.
但是在我运行之后,dist/public/fonts它就不存在了.为什么不?
所以我知道如何动态设置密钥如下:
var hashObj = {};
hashObj[someValue] = otherValue;
Run Code Online (Sandbox Code Playgroud)
但我没有看到任何答案map():
var list = ['a', 'b', 'c'];
var hashObject = list.map(function(someValue) {
return { someValue: 'blah' };
});
// should return: [ {'a': 'blah'}, {'b': 'blah'}, {'c': 'blah'} ];
Run Code Online (Sandbox Code Playgroud)
我知道我可以在for循环中这样做,但这在javascript使用中是不可能的map()吗?
我有一个jinja2模板,我重复使用不同的Flask路线.所有这些路由都只有一个必需参数,只处理GET请求,但有些路由可能有额外的参数.
有没有办法将额外的参数附加到url_for()?
就像是
url_for(my_custom_url, oid=oid, args=extra_args)
Run Code Online (Sandbox Code Playgroud)
将呈现给(取决于路由端点):
# route 'doit/<oid>' with arguments
doit/123?name=bob&age=45
# route 'other/<oid>' without arguments
other/123
Run Code Online (Sandbox Code Playgroud)
我的用例是提供预定义查询参数的链接:
<a href=" {{ url_for('doit', oid=oid, args=extra_args }} ">A specific query</a>
<a href=" {{ url_for('other', oid=oid) }} ">A generic query</a>
Run Code Online (Sandbox Code Playgroud)
我想在没有JavaScript的情况下运行这个模板,所以如果可能的话,我不想分配一个点击监听器并使用AJAX来GET为每个链接做一个请求.
我有一个JWT令牌,我想存储在cookie中.cookie需要至少设置HttpOnly标志,但我还想将Secure标志设置为true.
从角度文档我知道我可以将我的令牌存储在这样的cookie中:
// using 'ngCookies'
createToken(jwt_token) {
$cookies.put('jwt', jwt_token);
},
retrieveToken() {
return $cookies.get('jwt');
}
Run Code Online (Sandbox Code Playgroud)
但目前尚不清楚如何指定HttpOnly和Secure标志.该文件说有一个选项字段put()和get(),但是随后它提到 $cookiesProvider.我不确定它是如何适应的,或应该在哪里声明,或者每次我做一个put()或者是否需要设置get()?
它会是这样的:
createToken(jwt_token) {
$cookiesProvider['domain'] = 'www.mydomain.com';
$cookiesProvider['secure'] = true;
$cookies.put('jwt', jwt_token);
},
retrieveToken() {
$cookiesProvider['domain'] = 'www.mydomain.com';
$cookiesProvider['secure'] = true;
return $cookies.get('jwt');
}
Run Code Online (Sandbox Code Playgroud)
还是完全错了?我也没有看到任何HttpOnly标志,但我确实看到domain了我设置的标志www.mydomain.com.这相当于HttpOnly = true吗?
如何手动填写表格然后进行验证?
class TestForm(Form):
name = StringField('name', validators=[InputRequired()])
age = IntegerField('age', validators=[InputRequired()])
Run Code Online (Sandbox Code Playgroud)
我尝试使用任意数据构建表单并验证:
data = {'name': 'bob', 'age': 33}
tform = TestForm(name=data['name'], age=data['age'])
if tform.validate():
print 'success!'
else:
print tform.errors
Run Code Online (Sandbox Code Playgroud)
结果打印出错误:
{'age': [u'This field is required.']}
Run Code Online (Sandbox Code Playgroud)
这很奇怪,因为name即使我将他们都提供给了我的朋友,也没有抱怨TestForm。我究竟做错了什么?
Flask 推荐使用 Flask-Uploads 模块来处理上传。我想拒绝任何超过特定大小的文件。有几种解决方案:
从文档:
此外,您还可以使用 patch_request_class 来修补应用的 request_class 以具有最大上传大小。
patch_request_class(app, 32 * 1024 * 1024)
Run Code Online (Sandbox Code Playgroud)
MAX_CONTENT_LENGTH 是拒绝大于您想要的文件上传的正确方法,
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
# save to disk first, then check filesize
request.files['file'].save('/tmp/foo')
size = os.stat('/tmp/foo').st_size
Run Code Online (Sandbox Code Playgroud)
-或者-
# save to memory, then check filesize
blob = request.files['file'].read()
size = len(blob)
Run Code Online (Sandbox Code Playgroud)
我MAX_CONTENT_LENGTH在官方文档中没有看到提到,它甚至没有像 SO 帖子那样手动检查文件大小。这两种方法最终是否相同,还是存在(大/微妙?)差异?另外,是patch_request_class先将文件保存到磁盘以确定总上传大小,还是保存到内存中?
部署应用程序之前的常规约定是缩小所有资产(css、html、js)。这通常假设所有资产都在一个独立的文件中(即所有 js 代码都在/js/mycode.js.
但是,我编写了一堆带有<script>标签的 jinja2 模板,它们使用了模板的变量。这对于快速快速编写 UI 很有用,但我想知道将所有这些迁移到一个 js 文件中以便以后可以进行缩小的最佳方法是什么?
例如,我有很多包含内联 js 的模板:
<div class="some_content">
<button>{{mytext}}</button>
</div>
<script>
$(".some_content button").click(function() {
$(this).text("{{new_text}}");
$.post("{{url_for('doit', name=name)}}", function() {
console.log('Done!');
});
});
</script>
Run Code Online (Sandbox Code Playgroud)
我知道我可以将 js 代码填充到一个文件中,然后执行{% include 'mycode.js' %},但随后我会将所有 js 代码导入到模板中。一些模板具有继承性,因此执行 include 语句会导致文件多次将整个脚本加载到页面中(不好)。而且我不确定包含这样的脚本如何与缩小一起工作。
有没有一种好方法可以将所有内联 JS 代码移动到外部文件,而不会失去 jinja2 模板变量的好处,以便我可以缩小我的 javascript?或者更确切地说,缩小所有内联 JS 的好方法是什么?