Python的Flask框架中实现简洁的登录功能的教程Word文档下载推荐.docx
- 文档编号:18848276
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:5
- 大小:19.21KB
Python的Flask框架中实现简洁的登录功能的教程Word文档下载推荐.docx
《Python的Flask框架中实现简洁的登录功能的教程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Python的Flask框架中实现简洁的登录功能的教程Word文档下载推荐.docx(5页珍藏版)》请在冰豆网上搜索。
除了这些方法以外,类没有被要求实现其它方法。
下面是我们的User类(fileapp/models.py):
classUser(db.Model):
id=db.Column(db.Integer,primary_key=True)
nickname=db.Column(db.String(64),unique=True)
email=db.Column(db.String(120),unique=True)
role=db.Column(db.SmallInteger,default=ROLE_USER)
=db.relationship('
Post'
backref='
author'
lazy='
dynamic'
)
defis_authenticated(self):
returnTrue
defis_active(self):
defis_anonymous(self):
returnFalse
defget_id(self):
returnunicode(self.id)
def__repr__(self):
return'
User%r'
%(self.name)
is_authenticated方法是一个误导性的名字的方法,通常这个方法应当返回True,除非对象代表一个由于某种缘由没有被认证的用户。
is_active方法应当为用户返回True除非用户不是激活的,例如,他们已经被禁了。
is_anonymous方法应当为那些不被获准登录的用户返回True。
最终,get_id方法为用户返回唯一的unicode标识符。
我们用数据库层生成唯一的id。
用户加载回调
现在我们通过用法Flask-Login和Flask-OpenID扩展来实现登录系统
首先,我们需要写一个方法从数据库加载到一个用户。
这个方法会被Flask-Login用法(fileapp/views.py):
@lm.user_loader
defload_user(id):
returnUser.query.get(int(id))
记住Flask-Login里的userid始终是unicode类型的,所以在我们把id传递给Flask-SQLAlchemy时,有必要把它转化成integer类型。
登录视图函数
接下来我们要更新登录视图函数(fileapp/views.py):
fromflaskimportrender_template,flash,redirect,session,url_for,request,g
fromflaskext.loginimportlogin_user,logout_user,current_user,login_required
fromappimportapp,db,lm,oid
fromformsimportLoginForm
frommodelsimportUser,ROLE_USER,ROLE_ADMIN
@app.route('
/login'
methods=['
GET'
'
POST'
])
@oid.loginhandler
deflogin():
ifg.userisnotNoneandg.user.is_authenticated():
returnredirect(url_for('
index'
form=LoginForm()
ifform.validate_on_submit():
session['
remember_me'
]=form.remember_me.data
returnoid.try_login(form.openid.data,ask_for=['
nickname'
email'
returnrender_template('
login.html'
title='
SignIn'
form=form,
providers=app.config['
OPENID_PROVIDERS'
留意到我们导入了一些新的模块,其中有些后面会用到。
跟上个版本的改变很小。
我们给视图函数添加了一个新的装饰器:
oid.loginhandler。
它告诉Flask-OpenID这是我们的登录视图函数。
在方法体的开头,我们检测是是否用户是已经经过登录认证的,假如是就重定向到index页面。
这儿的思路是假如一个用户已经登录了,那么我们不会让它做二次登录。
全局变量g是Flask设置的,在一个request生命周期中,用来存储和共享数据的变量。
所以我猜你已经想到了,我们将把已经登录的用户放到g变量里。
我们在调用redirect()时用法的url_for()方法是Flask定义的从给定的view方法猎取url。
假如你想重定向到index页面,你h很可能用法redirect('
/index'
),但是我们有很好的理由让Flask为你构造url。
当我们从登录表单得到返回数据,接下来要运行的代码也是新写的。
这儿我们做两件事。
首先我们保存remember_me的布尔值到Flask的session中,别和Flask-SQLAlchemy的db.session混淆了。
我们已经知道在一个request的生命周期中用Flask的g对象来保存和共享数据。
沿着这条线路Flask的session供应了更多,更简单的服务。
一旦数据被保存到session中,它将在同一客户端发起的这次恳求和这次以后的恳求中永存而不会消亡。
数据将保持在session中直到被明确的移除。
为了做到这些,Flask为每个客户端建立各自的session。
下面的oid.try_login是通过Flask-OpenID来执行用户认证。
这个方法有两个参数,web表单供应的openid和OpenIDprovider供应的我们想要的list数据项。
由于我们定义了包含nickname和email的User类,所以我们要从找nickname和email这些项。
基于OpenID的认证是异步的。
假如认证胜利,Flask-OpenID将调用有由oid.after_login装饰器注册的方法。
假如认证失败那么用户会被重定向到login页面。
Flask-OpenID登录回调
这是我们实现的after_login方法(app/views.py)
@oid.after_login
defafter_login(resp):
ifresp.emailisNoneorresp.email=="
"
:
flash('
Invalidlogin.Pleasetryagain.'
redirect(url_for('
login'
user=User.query.filter_by(email=resp.email).first()
ifuserisNone:
nickname=resp.nickname
ifnicknameisNoneornickname=="
nickname=resp.email.split(]
user=User(nickname=nickname,email=resp.email,role=ROLE_USER)
db.session.add(user)
mit()
remember_me=False
if'
insession:
remember_me=session['
]
session.pop('
None)
login_user(user,remember=remember_me)
returnredirect(request.args.get('
next'
)orurl_for('
传给after_login方法的resp参数包含了OpenIDprovider返回的一些信息。
第一个if声明仅仅是为了验证。
我们要求一个有效的email,所以一个没有没供应的email我们是没法让他登录的。
接下来,我们将依据email查找数据库。
假如email没有被找到我们就认为这是一个新的用户,所以我们将在数据库中增加一个新用户,做法就像我们从之前章节学到的一样。
留意我们没有处理nickname,由于一些OpenIDprovider并没有包含这个信息。
做完这些我们将从Flasksession中猎取remember_me的值,假如它存在,那它是我们之前在loginview方法中保存到session中的boolean类型的值。
然后我们调用Flask-Login的login_user方法,来注册这个有效的登录。
最终,在最终一行我们重定向到下一个页面,或者假如在request恳求中没有供应下个页面时,我们将重定向到index页面。
跳转到下一页的这个概念很简洁。
比方说我们需要你登录才能导航到一个页面,但你现在并未登录。
在Flask-Login中你可以通过login_required装饰器来限定未登录用户。
假如一个用户想连接到一个限定的url,那么他将被自动的重定向到login页面。
Flask-Login将保存最初的url作为下一个页面,一旦登录完成我们便跳转到这个页面。
做这个工作Flask-Login需要知道用户当前在那个页面。
我们可以在app的初始化组件里配置它(app/__init__.py):
lm.login_view='
全局变量g.user
假如你留意力很集中,那么你应当记得在loginview方法中我们通过检查g.user来推断一个用户是否登录了。
为了实现这个我们将用法Flask供应的before_request大事。
任何一个被before_request装饰器装饰的方法将会在每次request恳求被收到时提前与view方法执行。
所以在这儿来设置我们的g.user变量(app/views.py):
@app.before_request
defbefore_request():
g.user=current_user
这就是它要做的一切,current_user全局变量是被Flask-Login设定的,所以我们只需要把它拷贝到更简单被访问的g变量就OK了。
这样,全部的恳求都能访问这个登录的用户,甚至于内部的模板。
index视图
在之前的章节中我们用假代码遗留了我们的index视图,由于那个时候我们系统里并没有用户和博客文章。
现在我们有用户了,所以,让我们来完成它吧:
/'
@login_required
defindex():
user=g.user
=[
{
'
{'
John'
},
body'
BeautifuldayinPortland!
'
Susan'
TheAvengersmoviewassocool!
}
]
index.html'
Home'
user=user,
=)
在这个方法中只有两处变动。
首先,我们增加了login_required装饰器。
这样表明白这个页面只有登录用户才能访问。
另一个改动是把g.user传给了模板,替换了之间的假对象。
现在可以运行我们的应用了。
当我们连接到你将会看到登陆页面。
记着假如你通过OpenID登录那么你必需用法你的供应者供应的OpenIDURL。
你可以下面URL中的任何一个OpenIDprovider来为你产生一个正确的URL。
作为登录进程的一部分,你将会被重定向到OpenID供应商的网站,你将在那儿认证和授权你共享给我们应用的一些信息(我们只需要email和nickname,放心,不会有任何密码或者其他个人信息被曝光)。
一旦登录完成你将作为已登录用户被带到index页面。
试试勾选remember_me复选框。
有了这个选项当你在扫瞄器关闭应用后重新打开时,你还是已登录状态。
注销登录
我们已经实现了登录,现在是时候来实现注销登录了。
注销登录的方法灰常简洁(fileapp/views.py):
/logout'
deflogout():
logout_user()
但我们在模板中还没有注销登录的链接。
我们将在base.html中的顶部导航栏添加这个链接(fileapp/templates/base.html):
html
head
{%iftitle%}
title{{title}}-microblog/title
{%else%}
titlemicroblog/title
{%endif%}
/head
body
divMicroblog:
ahref="
{{url_for('
)}}"
Home/a
{%ifg.user.is_authenticated()%}
|ahref="
logout'
Logout/a
/div
hr
{%withmessages=get_flashed_messages()%}
{%ifmessages%}
ul
{%formessageinmessages%}
li{{message}}/li
{%endfor%}
/ul
{%endwith%}
{%blockcontent%}{%endblock%}
/body
/html
这是多么多么简洁啊,我们只需要检查一下g.user中是否有一个有效的用户,假如有我们就添加注销链接。
在我们的模板中我们再一次用法了url_for方法。
更多信息请查看IT技术专栏
...
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Python Flask 框架 实现 简洁 登录 功能 教程