Python中的CSRF攻击与Session管理

2023-04-17 00:00:00 python 管理 攻击

CSRF(Cross-site request forgery)攻击是一种Web攻击,它利用了用户已经登录了一个网站这个特殊情况,向攻击者的恶意网站发送一个伪造的请求来执行一个未经许可的操作,比如修改用户的密码、转账等。Python中可以使用Flask-WTF来防御CSRF攻击。

首先安装Flask-WTF:

pip install flask-wtf

然后在Flask应用中导入Flask-WTF并配置密钥:

from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)

# 自定义密钥
app.config['SECRET_KEY'] = 'my secret key!'

# 启用CSRF保护
csrf = CSRFProtect(app)

在需要防御CSRF攻击的表单中,需要添加一个隐藏的input标签,用于传递CSRF令牌:

<form method="post" action="/submit">
  {{ form.hidden_tag() }}
  <input type="text" name="username">
  <input type="password" name="password">
  <button type="submit">提交</button>
</form>

在Flask-WTF中,表单可以通过Form类定义,如下所示:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired

class LoginForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired()])
    password = PasswordField('密码', validators=[DataRequired()])
    submit = SubmitField('登录')

在视图函数中,可以使用form.validate_on_submit()方法来进行表单验证:

from flask import Flask, render_template, request, flash, redirect
from .forms import LoginForm

app = Flask(__name__)
app.config['SECRET_KEY'] = 'my secret key!'

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        username = form.username.data
        password = form.password.data
        # 验证用户名密码是否正确
        if username == 'pidancode.com' and password == '123456':
            flash('登录成功!')
            return redirect('/')
        else:
            flash('用户名或密码错误!')
    return render_template('login.html', form=form)

Session管理是一种在Web开发中常见的技术,用于存储用户的登录信息、购物车等信息。在Flask中,Session可以通过Flask-Session扩展实现。

首先安装Flask-Session:

pip install flask-session

然后在Flask应用中配置Session:

from flask import Flask
from flask_session import Session

app = Flask(__name__)

# 配置Session
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis()
app.config['SESSION_COOKIE_NAME'] = 'my_cookie'
app.config['SECRET_KEY'] = 'my secret key!'

# 启用扩展
Session(app)

上面配置支持通过Redis存储Session数据,SESSION_COOKIE_NAME参数指定了Session的cookie名称。在视图函数中,可以通过session变量来存储或获取Session数据:

from flask import session, redirect, url_for

@app.route('/set_session')
def set_session():
    session['username'] = 'pidancode.com'
    return redirect(url_for('index'))

@app.route('/')
def index():
    username = session.get('username')
    return '用户名:{}'.format(username)

上面代码中,在/set_session路由处理函数中,存储了一个键为username,值为pidancode.com的Session信息。在/index路由处理函数中,通过session.get获取到了username对应的值,并显示在页面中。

相关文章