【简说Python WEB】用户身份验证--Werkzeug
系统环境:Ubuntu 18.04.1 LTS
Python使用的是虚拟环境:virutalenv
Python的版本:Python 3.6.9
【简说Python WEB】用户身份验证--Werkzeug
基本大多数web应用都有用户身份验证。
基本的身份验证,要不是用户名,要不是电子邮件地址。加上自己的密码。完成身份验证。
这里就是做一个完整的用户身份验证系统
Flask的security扩展
- FLask-Login:管理已经登录的用户会话
- Werkzeug:计算密码散列值,同时进行check
- itsdangerous:生成并check加密安全令牌
使用Werkzeug生成密码散列值
Werkzeug的security模块实现了散列值的计算。有两个函数,一个生成,另外一个核对
如下:
generate_password_hash(password,method='pbkdf2:sha256',salt_length=8)
三个输入参数:
- 第一个参数: 输入密码
- 第二个参数:pbkdf2_sha256加密验证算法
- 第三个参数:salt值字符串长度。
pbkdf2_sha256 + SALT盐值加密,是很可靠的一种加密方式。
输入的值是一个密码,输出的值返回密码散列值的字符串。基本默认值就够用了。
check_password_hash(hash, password)
这个参数从数据库中取出密码的hash值和输入的密码值进行校对。如果返回为True说明输入的密码正确。
在app/models.py
加入Werkzeug密码散列值
from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model):
#..
password_hash = db.Column(db.String(128))
@property
def password(self):
raise AttributeError('password is not a readable attribute')
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
在shell测试上述代码:
(zsdpy1) zsd@zsd-virtual-machine:~/Zflask$ flask shell
Python 3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0] on linux
App: app [production]
Instance: /home/zsd/Zflask/instance
>>> u = User()
>>> u.password = 'cat'
>>> u.password_hash
'pbkdf2:sha256:150000$bCVGWsku$752d59b87a450aac1b2ea9297e6475f2300fcdea4b589f788aa753e1a820c12d'
>>> u.verify_password('cat')
True
>>> u.verify_password('zsd')
False
>>> u2 = User()
>>> u2.password = 'cat'
>>> u2.password_hash
'pbkdf2:sha256:150000$oMmeJziP$92900571f3639e0dca770bbb94f83c64a22d3f510343446a32499c2f64783962'
可以看到u和u2的密码虽然都是cat,但是hash密码值确实不一样的。
这样手动写shell一步一步测试特别浪费时间,我们可以通过写单元测试,完成测试工作。如下:
tests/test_user_model.py
密码散列测试
import unittest
from app import create_app, db
from app.models import User
class UserModelTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app('testing')
self.app_context = self.app.app_context()
self.app_context.push()
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
self.app_context.pop()
def test_password_setter(self):
u = User(password='cat')
self.assertTrue(u.password_hash is not None)
def test_no_password_getter(self):
u = User(password='cat')
with self.assertRaises(AttributeError):
u.password
def test_password_verification(self):
u = User(password='cat')
self.assertTrue(u.verify_password('cat'))
self.assertFalse(u.verify_password('dog'))
def test_password_salts_are_random(self):
u = User(password='cat')
u2 = User(password='cat')
self.assertTrue(u.password_hash != u2.password_hash)
执行下列命令,做单元测试 :
(zsdpy1) $ flask test
test_app_exists (test_basics.BasicsTestCase) ... ok
test_app_is_testing (test_basics.BasicsTestCase) ... ok
test_no_password_getter (test_user_model.UserModelTestCase) ... ok
test_password_salts_are_random (test_user_model.UserModelTestCase) ... ok
test_password_setter (test_user_model.UserModelTestCase) ... ok
test_password_verification (test_user_model.UserModelTestCase) ... ok
----------------------------------------------------------------------
Ran 6 tests in 2.760s
这样就相当于自动化测试,直接测试了刚刚shell做得测试工作。
【简说Python WEB】用户身份验证--Werkzeug的更多相关文章
- Python tkinter 实现简单登陆注册 基于B/S三层体系结构,实现用户身份验证
Python tkinter 实现简单登陆注册 最终效果 开始界面 注册 登陆 源码 login.py # encoding=utf-8 from tkinter import * from ...
- IdentityServer4 使用OpenID Connect添加用户身份验证
使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...
- MVC4商城项目二:用户身份验证的实现
用户身份验证,依赖于 forms 身份验证类:FormsAuthentication,它是一串加密的cookie 来实现对控制器访问限制和登陆页面的访问控制.它在浏览器端是这样子的: 需求:我们要实现 ...
- asp.net用户身份验证时读不到用户信息的问题 您的登录尝试不成功。请重试。 Login控件
原文:asp.net用户身份验证时读不到用户信息的问题 您的登录尝试不成功.请重试. Login控件 现象1.asp.net使用自定义sql server身份验证数据库,在A机器新增用户A,可以登录成 ...
- 【转载】IdentityServer4 使用OpenID Connect添加用户身份验证
使用IdentityServer4 实现OpenID Connect服务端,添加用户身份验证.客户端调用,实现授权. IdentityServer4 目前已更新至1.0 版,在之前的文章中有所介绍.I ...
- 第11章 使用OpenID Connect添加用户身份验证 - Identity Server 4 中文文档(v1.0.0)
在本快速入门中,我们希望通过OpenID Connect协议向我们的IdentityServer添加对交互式用户身份验证的支持. 一旦到位,我们将创建一个将使用IdentityServer进行身份验证 ...
- asp.net的forms身份验证 单用户身份验证
asp.net的forms身份验证 单用户身份验证 首先要配置Web.config文件 <system.web> <authentication mode="Forms& ...
- 【简说Python WEB】Flask应用的文件结构
目录 [简说Python WEB]Flask应用的文件结构 1.文件结构的目录 2.配置程序--config.py 3.app应用包 4.剥离出来的email.py 5.蓝本(BLueprint)的应 ...
- 【简说Python WEB】数据库
目录 [简说Python WEB]数据库 数据库表 docker安装MySQL Flask-SQLAlchemy操纵MySQL数据库 初始化 定义模型 定义关系 数据库的CRUD操作 创建表 inse ...
- 【简说Python WEB】Web应用部署
目录 [简说Python WEB]Web应用部署 应用层 缓存层 数据层 Gunicorn 的应用 1.安装Gunicorn 2.Gunicorn的启动 Nginx 的应用 1.docker方式部署安 ...
随机推荐
- UE4_C++实现TimeLine
主要实现蓝图节点中时间轴的功能. 目前UE提供了两种实现方式,一个是使用FTimeLine其是一个时间轴的结构体:另一种方式是使用UTimeLineComponent,其是一个时间轴组件类.两者内部定 ...
- linux下firefox用css配置把网页设置成黑白
网址输入 about:config 忽略警告 toolkit.legacyUserProfileCustomizations.stylesheets设置为true 在 /home/user/.mozi ...
- 程序员/后端开发方向Java 跳槽注意事项(简历和面试经验分享)
程序员/后端开发方向Java 跳槽注意事项(简历和面试经验分享) 应届生面试经验参考:https://www.cnblogs.com/rainbow-1/p/16779048.html 简历: 1.个 ...
- #排列组合#CF1550D Excellent Arrays
洛谷传送门 CF1550D 分析 对于excellent的 \(a\) 来说 \(|a_i-i|=x\) 的值是固定的,考虑枚举它 一半正一半负时函数值是最大的,当 \(n\) 为奇数时要分为两种情况 ...
- #线段树#洛谷 4340 [SHOI2016]随机序列
题目 分析 可以发现加号和减号会抵消掉,真正有用的答案就是第一段的乘积. 那也就是 \(\sum_{i=1}^nS_i*2*3^{n-i-1}\),其中 \(S_i\) 表示 \(a_1\) 到 \( ...
- C#的无边框窗体改变大小解决方案 - 开源研究系列文章
这次继续研究无边框窗体需要的功能.其实就是把有边框的默认窗体的一些功能进行实现而已.不过不同的人不一定相同的代码,所以笔者尽量用最简单有效的方法例子让读者能够直接对代码进行复用,以节省时间和人力.这次 ...
- Git分支教程:详解分支创建、合并、删除等操作
Git是一种强大的分布式版本控制系统,它的分支功能使得团队协作和代码管理变得更加灵活和高效.分支可以让开发人员在不影响主线开发的情况下进行并行开发和实验性工作.本篇博客将详解Git分支的创建.合并.删 ...
- Numpy数组索引和切片
数组可以通过索引或切片的方式进行访问或修改,数组切片x[start:stop:step],与Ptyhon内置的list标准索引和切片类似,只是数组产生的是一个非副本视图,根据条件索引的值如果修改,直接 ...
- C# DevExpress下GridControl控件的增删查改
DevExpress的GridControl控件可以从任何数据源绑定数据并进行增删查改等操作,和VS自带的dataGridView控件对比,GridControl控件可以实现更多自定义的功能,界面UI ...
- Rust——生命周期
简而言之,即引用的有效作用域:一般情况下编译器会自动检查推导,但是当多个声明周期存在时,编译器无法推导出某个引用的生命周期,需要手动标明生命周期. 悬垂指针 悬垂指针是指一个指针指向了被释放的内存或者 ...