python客户端修改session_19.设置服务器端Session【番外】

在11.保存登录状态与注销功能这篇文章中,我们使用了session来保存username,实际上Flask默认的session功能,是客户端session(client-side session),与之相对的是服务器端session(server-side session)。简单来说,这里的客户端session是将username加密后,以cookie的形式返还给客户端,客户端后续访问网站就携带着这个cookie,服务器解密cookie得到username。也就是说,如果知道了加密方法和cookie内容,就可以解密出username,这样是不够安全的。

今天我们来实现服务器端session(server-side session),原理很简单,实际上在【python socket编程】—— 5.实现cookie和session这篇文章中我们已经做过了。现在我们用数据库来保存session,并为其设置有效期。整个逻辑是这样的:用户登录后,生成一个随机字符串,将其作为session id,与对应的username和过期时间一起存入数据库,然后将session id作为cookie返回给客户端,客户端后续访问时,携带着含有session id的cookie,服务器通过cookie中的session id在数据库中检索session数据,判断登录状态。

建立一个sessions表(ORM模型)来存储session,字段如下:

class MySession(db.Model):

__tablename__ = 'sessions'

id = db.Column(db.Integer, primary_key=True, autoincrement=True)

# s_id代表session id,也是后面返回给客户端的cookie

s_id = db.Column(db.String(24), nullable=False)

username = db.Column(db.String(64), nullable=False)

start_time = db.Column(db.DateTime, nullable=False)

expire_time = db.Column(db.DateTime, nullable=False)

视图函数代码如下:

@app.route('/session/', methods=['GET', 'POST'])

def test_session():

username = None

if request.method == 'GET':

s_id = request.cookies.get('sid')

if s_id:

mysession = MySession.query.filter(MySession.s_id == s_id).first()

if mysession and mysession.expire_time > datetime.now():

username = mysession.username

return render_template('session.html', username=username)

else:

username = request.form.get('username')

s_id = random_strings(24)

now = datetime.now()

expire_time = now + timedelta(seconds=10)

mysession = MySession(s_id=s_id, username=username, start_time=now, expire_time=expire_time)

db.session.add(mysession)

db.session.commit()

response = make_response(redirect(url_for('test_session')))

response.set_cookie('sid', s_id)

return response

我们从POST方法讲起,当用户POST一个username过来时(为了简单,session.html只有用户名没有密码),生成一个随机字符串(random_strings是自己编写的一个小函数)作为session id,然后获取现在的时间now和过期时间expire_time(为了演示方便,过期时间是10秒之后),然后将这些信息存入MySession模型中,最后使用make_response方法生成一个response对象(这个对象有set_cookie方法,这也是Flask设置cookie的常规方法),并为其设置cookie,set_cookie第一个参数'sid'是key,第二个参数是value(session id),之后返回response对象。当请求是GET时候,首先就会使用request.cookies.get('sid')去获取cookie中的session id,如果获取到并且还在过期时间内,则向html传入username表明当前已经登录的用户。

最后html的内容如下:

Title

{% if username %}

Welcome {{ username }}

Logout

{% else %}

Username:

Login

{% endif %}

效果展示:

未登录时:

登录后:

此时数据库中的session信息:

浏览器中的cookie内容:

过期之后浏览器仍然携带这个cookie,但刷新网页又变成未登录的状态了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值