Flask登录初探
0.python能干啥,首先就是让小学生学编程啊。接续上篇,为了实现前后端登录打通,开始搭建后端相关
1.python装起来,考虑使用前后端分离,那么就用Flask框架
2.Flask装起来,按照Flask官网,他推荐只用虚拟机来运行flask程序,这是蛮好的思路,已阅,推广之。(https://dormousehole.readthedocs.io/en/latest/installation.html#installation)
3.首先安装虚拟环境,找个文件夹在其内运行CMD命令:py -m venv venv 命令执行完毕后,就会在此文件夹下生成venv子文件夹,里面有一堆文件。
4.运行venv目录下的scripts目录下的activate。即:venv\scripts\activate.如下图所示。(其实对于任何py程序都可以如此创建虚拟环境,不需要改任何字符。习惯这么模式后,看到venv就知道是在虚拟环境下运行)
5.就在虚拟环境目录下,运行pip install Flask。注意不要在其他目录下运行,否则虚拟环境白搞了。
6.照这教程敲一波代码,体会一下Flask的洪荒之力 https://dormousehole.readthedocs.io/en/latest/quickstart.html#quickstart
7.经过七七四十九天,五行代码敲击完毕。准备运行
8.注意在powershell和cmd两种命令行 指令有点不一样。
8.1 在cmd下是这样的:
set FLASK_APP=hello.py
flask run
8.2 在powershell下是这样的:
$env:FLASK_APP = "hello.py"
flask run
9.运行后,效果
10.浏览器中打开网址,就能看到东西了。
------------------------------------------------------------------------------------------------------------------------
0.上一波是初试Flask,这一波进入主题,走一个登录
1.如下图全部代码
2.红框圈出的,是生成secretKey的方法,在cmd下运行红框中的代码,将其copy到secretKey即可。如果忽略secretKey,那么在使用session时,python就会提示 "session不可用因为没有使用secertKey",其实就是用来加密cookie的。
3.flask run 之后,就会展现下列效果
4.到此为止,简单实现了登录过程。并且使用了flask提供的session模块,如果把session.clear注销,将能实现记住登录用户的功能。
5.当然一个登录,需要有数据库交互,还要和前端做关联。下面暂时使用 用户 列表,来实现登录验证
6.改造了两部分,一个是添加了USERS列表。第二个是在helloworld函数内添加用户合法性验证代码。
需要注意的是。我这里使用了generate_password_hash函数用于生成密码的散列值,密码明文存储这是大忌。
另外这个散列函数会有salt值,这会导致每次用相同密码产生的散列值是不一样的。所以只能使用check_password_hash 来判定密码是否一致。具体加salt实现原理,自己看源码吧。
7.把USERS列表用数据库替代,就实现了真正意义上的用户登录。把vue前端和本后端代码关联暂缓实现,再次深入登录过程,尝试使用Flask_login组件,来重构上述过程。之后再对jwt做个demo。
------------------------------------------------------------------------------------------------------------------
0.第三波强烈来袭,用flask_login走一波上述逻辑 ,老规矩 祭出官网 镇住bug (https://flask-login.readthedocs.io/en/latest/index.html)。
有一点要注意,flask_login有个中文站点,比英文主站版本要低,可以结合对照看,但小部分内容不一样。注意识别。
1.pip install flask-login 用这句话把其装起来,当然要在虚拟机venv下安装了。千万别忘啦。
2.根据官网步骤是能完全搞出来的。我在这里多嘴简化一下。flask_login 只需套着来就行,
先添加这两行代码 login_manager = LoginManager()
login_manager.init_app(app)
然后实现user 类。可以由UserMixin继承获得。这个user类必须实现,别问为什么。学渣没有资格问为什么,抄就行了。
还要把这块代码放进来 @login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
最后,在需要登录验证的函数上加 注解 @login_required
3.大致流程就是这样。正式走一遍代码。看我这个学渣能不能抄明白。
from flask import Flask,session,redirect,url_for,request from werkzeug.security import generate_password_hash,check_password_hash from flask_login import LoginManager,login_user,logout_user,login_required,current_user from user import User,USERS app = Flask(__name__) app.secret_key=b'\x12\xb6\xc0\xdd6^!\xf9\x9b\x83\x95G\x93K_9' #python -c "import os; print(os.urandom(16))" login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'default' @login_manager.user_loader def load_user(user_id): return User.get(user_id) @app.route('/login2', methods=['GET', 'POST']) def login2(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] user = User.queryUser(username) if (user != None) and (user.verifyPassword(password)) : login_user(user) return "hello flaskLogin:{}@{} ".format(username, password) else: return " username or password is not correct" else: return ''' <form method="post"> <p><input type=text name=username> <p><input type=password name=password> <p><input type=submit value=Login> </form> ''' @app.route("/logout2") @login_required def logout2(): logout_user() return 'bye bye ' @app.route('/index') @login_required def index(): return '我爱你 祖国 (来自' + current_user.username +'的心声)' @app.route('/default') def default(): return '祖国万岁(请使用login2登录)' @app.route('/') def hello_world(): if session.get('username') == None : return redirect(url_for('login')) else: username = session.get('username') password = session.get('password') #session.clear() for user in USERS: if (user.get("name") == username) and (check_password_hash(user.get("password"),password)): return " hello world:{}@{} ".format(username, password) return " username or password is not correct" @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': session['username'] = request.form['username'] session['password'] = request.form['password'] return redirect(url_for('hello_world')) else: return ''' <form method="post"> <p><input type=text name=username> <p><input type=password name=password> <p><input type=submit value=Login> </form> ''' @app.route('/logout') def logout(): session.pop('username') session.pop('password') return 'bye bye'
User.py
from flask_login import UserMixin from werkzeug.security import check_password_hash, generate_password_hash USERS = [ { "id":1, "name":"admin", "password":generate_password_hash('123') }, { "id":2, "name":"李四", "password":generate_password_hash('123') }, ] class User(UserMixin): def __init__(self,user): self.username = user.get("name") self.password_hash = user.get("password") self.id = user.get("id") @staticmethod def queryUser(username): for user in USERS: if (user.get('name') == username) : return User(user) return None def verifyPassword(self,password): if self.password_hash is None: return False return check_password_hash(self.password_hash,password) def get_id(self): return self.id def get(user_id): print('get(user_id):'+str(user_id)) print('get(user_id):'+str(type(user_id))) if not user_id: print('if not user_id:') return None for user in USERS: print('user.get("id"):' + str(user.get('id'))) print('user.get("id"):' + str(type(user.get('id')))) if str(user.get('id')) == str(user_id) : print('User(user)') return User(user) print('None') return None
4.上述代码,执行效果如下:
5.从登录到鉴权到注销用户。这一套基本体系已经构建完毕。当然flasklogin还有不少小技能需要挖掘。