用户系统和Flask-Login介绍

来源:互联网 发布:linux教学视频百度云 编辑:程序博客网 时间:2024/05/16 15:08

目录:

注册

登录

浏览

Flask-Login

数据安全性

个人页面AJAX实现


注册

一、流程

1 用户名合法性检测(长度、敏感词、重复、特殊字符)

2 MD5密码salt加密,密码强度检测

3 用户邮件/短信激活


注意:验证码内部思路

打开一个网页,下发一个key,同时实时生成一张图片,验证码是由该图片生成的,而非数据库中存储的图片,否则易被破解;

后台记录图片是由哪几个字符生成的,与用户提交的数据进行匹配。


二、代码实现

1 login.html文件

将login.html文件基于base.html文件,即login.html文件继承base.html文件,将页面的顶部和底部都继承自base.html,易于维护。

注意修改block中title和css。


2 views.py文件

添加路由@app.route('/reloginpage/'),并定义reloginpage方法,返回render_template('login.html');

添加路由@app.route('/reg/'),并以reg方法,获取request的username和password,并去掉字符串前后的空格;

注意:因为reg()方法是POST请求,因此要在指定路由时添加methods参数,将post和get赋值给methods;


3 models.py文件

修改User类,添加salt属性,默认情况为空字符串


4 views.py文件

在reg方法中,检查用户输入的用户名是否已经注册,即从数据库中查找是否有相同的username;

若存在,重定向到登录页面,并使用flash()方法显示提示信息,第一个参数是提示用的字符串,第二个参数是指定提示消息的类别category,可在get_flashed_messages()方法中获取指定类别的提示消息;


在reg方法中,检查用户名或密码是否为空,若是,则像上述方法一样重定向登录页面,并提示相应信息;


在reg方法中,添加盐salt,用于增加密码强度,随机抽出10个字符,并用'.'将其连接;

首先导入hashlib模块,调用hashlib的md5()方法生成一个md5 hash对象,该对象调用update()方法对密码和盐组合的字符串进行md5加密的更新处理,该对象调用hexdigest()方法将加密后的十六进制结果赋值给password;

创建User类对象,添加到数据库中并提交会话;


5 app.conf文件

Flask项目中,session、cookie以及一些第三方扩展都会用到secret_key值;

尽量设置为一个很难猜到的值,随机值更加,可使用os模块的urandom方法获取随机值;

在app.conf文件中,对app.secrect_key或app.config['SECRET_KEY']或app.config.update()进行赋值,如下:

app = Flask(__name__)app.secret_key = '\xca\x0c\x86\x04\x98@\x02b\x1b7\x8c\x88]\x1b\xd7"+\xe6px@\xc3#\\'# orapp.config['SECRECT_KEY'] = '\xca\x0c\x86\x04\x98@\x02b\x1b7\x8c\x88]\x1b\xd7"+\xe6px@\xc3#\\'# orapp.config.update(SECRECT_KEY = '\xca\x0c\x86\x04\x98@\x02b\x1b7\x8c\x88]\x1b\xd7"+\xe6px@\xc3#\\')


6 views.py文件

在reloginpage方法中,使用get_flashed_messages()方法获取消息,其中with_categories参数赋值为False,True表示返回元组,False表示只返回消息文本;category_filter参数过滤flash消息,只获取指定category的flash消息;

msg = ''for m in get_flashed_messges(with_categories = False, category = ['reglogin']):msg = msg + m

在返回的reder_temlpate()方法中将msg传入,以供对应HTML文件使用msg;


7 login.html文件

提示消息是在特定情景下显示,因此在login.html文件中需要先判断有无msg,若有则显示提示信息,若无,则显示“注册用户”;




登录/登出

一、登录

1 输入用户名和密码后提交到服务器,服务器密码校验/三方校验回调,若正确则token登记

a 服务器端:token关联userid

b 客户端:存储token(app存储本地,浏览器存储cookie)


2 服务器/客户端token有效期设置(记住登录)

注意:token可以是sessionid,或cookie中一个key;


二、登出

服务器/客户端token删除

session清理


页面浏览

一、客户端

带token的HTTP请求


二、服务端

1 根据token获取用户id

2 根据用户id获取用户具体信息

3 用户和页面访问权限处理

4 渲染页面/跳转页面




Flask-Login

一、介绍

1 官网

http://flask-login.readthedocs.io/en/latest/


2 功能

2.1 初始化

login_manager=LoginManager(app)

2.2 回调函数(通过session中的id获取用户信息)

@login_manager.user_loader

def load_user(user_id):

return User.query.get(user_id)

2.3 User用户接口

is_authenticated:验证认证过

is_active:是否激活

is_anonymous:是否匿名

get_id():获取用户id


3 核心函数和属性

login_user(user):登录用户

logout_user():登出用户

login_required:指定页面登录后才能访问

current_user:当前用户信息


二、代码实现

1 init.conf文件——初始化

from flask_login import LoginManagerlogin_manager = LoginManager(app)

login_manager.login_view = '/regloginpage/'   # 若用户未登录,则自动跳转到指定页面,而不是提示Unauthorized;


2 models.py文件

通过session的id获取用户信息:

from ImageSharing import login_manager

@login_manager.user_loader
def load_user(user_id):
return User.query.get(user_id)

在User模型中必须实现is_authenticated、is_active、is_anonymous、get_id方法:

def is_authenticated(self):
return True

def is_active(self):
return True

def is_anonymous(self):
return False

def get_id(self):
return self.id


3 view.py文件

from flask_login import login_user, logout_user, current_user, login_required

实现注册成功后自动登录,则在reg方法中,在提交会话给数据库后添加如下代码:

login_user(user)


实现切换到/logout/路由,自动登出,则添加路由,使用logout_user()方法,如下:

@app.route('/logout/')

def logout():

logout_user()

return redirect('/')


实现在/profile/页面,需要登录才能访问,则添加login_required属性:

@app.route('/profile/<int:user_id>/')

@login_required

def profile(user_id):

// ... ...


添加登录路由,实现与注册类似的功能:

@app.route('/login/', methods={'get','post'})
def login():
username = request.values.get('username').strip()
password = request.values.get('password').strip()
if username == '' or password == '':
return redirect_with_msg('/regloginpage/', u'用户名或密码不能为空', category='reglogin')
user = User.query.filter_by(username=username).first()
if user == None:
return redirect_with_msg('/regloginpage/', u'用户名不存在', category='reglogin')

m = hashlib.md5()
m.update(password+user.salt)
if(m.hexdigest()!=user.password):
return redirect_with_msg('/regloginpage/', u'密码错误', category='reglogin')

login_user(user)

next = request.values.get('next')
if next != None and next.startswith('/'):
return redirect(next)

return redirect('/')


4 base.html文件

右上角的小人图标应该是动态变化,即若用户已登录,点击图标显示的是登录用户的个人主页,若未登录,则跳转到登陆注册页面,判断标准是current_user属性;

{% if current_user.is_authenticated %}
<a class="profile-ico" href="/profile/{{current_user.id}}">{{current_user.username}}</a>
{% else %}
<a class="profile-ico" href="/regloginpage/">登录注册</a>
{% endif %}


5 index.html文件

在首页的标题添加用户名,current_user是全局可用的;

{% block title %}首页-{{current_user.username}}{% endblock %}


6 views.py文件和login.html文件

6.1 views.py文件

输入/logout/切换到登出页面,再点击自动跳转到登陆注册页面,但此时的URL形如:

http://127.0.0.1:5000/regloginpage/?next=%2Fprofile%2F100%2F

其中,%2F是URL编码,其实是斜线/;

好的用户交互体验是在此情况下登录后自动跳转到目标页面;


在regloginpage()方法中,返回的render_template的参数列表中添加next参数,用于获取请求中的next参数;

return render_template('login.html', msg=msg, next=request.values.get('next'))


6.2 login.html文件

在form表单标签下,添加input标签,类型是隐藏的,

<input type="hidden" name="next" value="{{next}}"/>

提交给后台的的表单中就包含next属性,则后台的login就可获取request请求中的next属性,从而进行处理;


6.3 views.html文件

在login方法中,登录后先获取next属性,判断是否为空且是否以'/'开头,若是则自动跳转到next属性指定的页面,若不是则自动跳转到主页;

login_user(user)

next = request.values.get('next')
if next != None and next.startswith('/'):
return redirect(next)

return redirect('/')

同样地,把注册页面也改为相应逻辑;




用户数据安全性

1 HTTPS注册页

HTTPS交互是加密的,用户信息的提交是不可见的;


2 公钥加密私钥解密,支付宝h5页面的支付密码加密

3 用户密码salt防止破解(CSDN,网易邮箱未加密密码泄露)

4 token有效期

5 单一平台的单点登录,登录IP异常检测

6 用户状态的权限判断

7 添加验证码机制,防止爆破和批量注册




个人页面AJAX实现

一、AJAX(异步数据交互)优势

1 页面不刷新

2 体验更好

3 传输数据更少

4 AAP/网站通用


拓展

统一的数据格式:{code: 0, msg: '', data: ''}

例子:牛客网投递登录框,点赞登录框


二、代码实现


0 0