1. Flask框架中的session:
在Flask中,我们可以使用session来存储和获取用户的信息。session是一个字典对象,可以方便地在各个页面之间传递数据。在使用session之前,需要配置一个秘钥(secret key)来保护session中的数据安全。下面我们来详细了解Flask框架中session的设置。
1.1. 配置秘钥:
在Flask应用程序中,我们需要为session设置一个秘钥来保证session中存储的数据安全。可以使用Flask对象的secret_key
属性或者app.secret_key
方法来配置秘钥。例如:
from flask import Flask
app = Flask(__name__)
app.secret_key = 'my_secret_key'
或者
from flask import Flask
app = Flask(__name__)
app.config['SECRET_KEY'] = 'my_secret_key'
这样就为Flask应用程序设置了一个秘钥为my_secret_key
的session。
1.2. 设置session:
我们可以使用session
全局对象来设置session中的值。例如:
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'my_secret_key'
@app.route('/')
def index():
session['username'] = 'John'
return 'Session username set!'
if __name__ == '__main__':
app.run()
这样,我们通过session['username'] = 'John'
将用户名John
存储到了session中,下一次再访问该应用程序时,我们可以通过读取session值来获取该用户名。
1.3. 获取session:
我们可以使用session
全局对象来读取session中的值。例如:
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'my_secret_key'
@app.route('/')
def index():
username = session.get('username')
if username:
return 'Hello, {}!'.format(username)
else:
return 'Session username not set!'
if __name__ == '__main__':
app.run()
这样,我们通过session.get('username')
获取session中存储的用户名,并使用if
语句判断该用户名是否存在。如果存在,返回欢迎信息,否则返回相应提示。
1.4. 永久化session:
在默认情况下,Flask中的session是有限制的,这意味着session只能在用户会话期间持续存储。如果用户关闭浏览器或重新启动计算机,则session将丢失。为了避免这种情况,我们可以使用PermanentSessionInterface
类来创建永久化session。
from flask import Flask, session
from flask_session import Session
app = Flask(__name__)
app.config['SECRET_KEY'] = 'my_secret_key'
app.config['SESSION_TYPE'] = 'filesystem'
Session(app)
@app.route('/')
def index():
session['username'] = 'John'
return 'Session username set!'
if __name__ == '__main__':
app.run()
在这个例子中,我们使用Flask-Session扩展中的Session
类来创建永久化session。我们需要将SESSION_TYPE
设置为filesystem
,这将会把session存储到文件系统中。需要注意的是,如果我们使用的是多进程服务器,例如Gunicorn,我们需要使用其他的session存储方式,例如将session存储到Redis中。
1.5. 删除session:
如果用户需要退出登录,我们可以使用session.pop()
方法删除session中的特定键值对,或者使用session.clear()
方法删除整个session。例如:
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'my_secret_key'
@app.route('/logout')
def logout():
session.pop('username', None)
return 'Logged out!'
if __name__ == '__main__':
app.run()
这个例子中,我们定义了一个logout()
路由,通过session.pop('username', None)
删除session中的用户名键值对,然后返回相应提示。
2. session的安全性:
对于使用session存储敏感信息的应用程序,有可能会遭受到会话劫持(Session Hijacking),即黑客在用户登录后获取到session ID,然后使用这个session ID来伪造用户的身份,从而实施攻击。为了保护session的安全性,我们需要采取一些措施。
2.1. 使用https:
使用https(HTTP Secure)可以有效地防止会话劫持攻击。https连接是基于SSL/TLS协议的安全连接,可以对传输的数据进行加密。如果我们的应用程序中需要使用session存储敏感信息,我们应该开启https连接。
2.2. 设置session过期时间:
我们可以设置session的过期时间来保证session ID的安全性。在Flask中,我们可以使用PERMANENT_SESSION_LIFETIME
配置项来设置session的过期时间。例如:
from datetime import timedelta
app = Flask(__name__)
app.secret_key = 'my_secret_key'
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)
在这个例子中,我们将PERMANENT_SESSION_LIFETIME
设置为30分钟,这意味着session ID会在30分钟后过期。此外,我们还可以在设置session的时候指定过期时间。例如:
from flask import Flask, session
from datetime import datetime, timedelta
app = Flask(__name__)
app.secret_key = 'my_secret_key'
@app.route('/')
def index():
session['username'] = 'John'
session['expires_at'] = datetime.now() + timedelta(minutes=30)
return 'Session username set!'
if __name__ == '__main__':
app.run()
在这个例子中,我们将expires_at
键值对设置为过期时间,在读取session的时候,我们可以通过datetime.now()
方法获取当前时间,然后与expires_at
比较,来判断session是否过期。
2.3. 使用CSRF保护:
CSRF(Cross-site request forgery)攻击是一种利用用户已经身份验证的安全漏洞,通过伪造恶意请求,从而获取用户的数据或者执行一些危险操作。对于使用session存储敏感信息的应用程序,我们需要使用CSRF保护来防止这种攻击。
在Flask中,我们可以使用Flask-WTF
扩展中的form.hidden_tag()
方法来生成隐藏的表单字段,从而添加CSRF保护。例如:
from flask import Flask, session, render_template_string
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.secret_key = 'my_secret_key'
app.config['WTF_CSRF_SECRET_KEY'] = 'my_csrf_secret_key'
class MyForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
def index():
form = MyForm()
if form.validate_on_submit():
session['name'] = form.name.data
return 'Session name set!'
return render_template_string('''
<form method="post" action="/">
{{ form.hidden_tag() }}
{{ form.name.label }} {{ form.name() }}
{{ form.submit() }}
</form>
''', form=form)
if __name__ == '__main__':
app.run()
在这个例子中,我们定义了一个MyForm
表单类,使用DataRequired
验证器来验证表单字段是否为空。在表单中使用{{ form.hidden_tag() }}
生成隐藏的表单字段,添加CSRF保护。通过这个方式,我们可以避免CSRF攻击。
3. 总结:
在Flask框架中,session功能十分强大,可以方便地在各个页面之间传递数据。但是,对于使用session存储敏感信息的应用程序,我们需要采取一些措施来保证session的安全性,例如使用https连接、设置session过期时间、使用CSRF保护等。