一、項(xiàng)目結(jié)構(gòu)和基本的依賴包
apps
? ? ? ? -user
? ? ? ? __init__.py
authen
? ? ? ?__init__.py
? ? ? ? token.py
ext
? ? ? ? __init__.py
util.py
? ? ? ?public.py
? ? ? ? __init__.py
app.py
依賴包
alembic==1.8.1
click==7.1.2
Flask==1.1.4
Flask-Migrate==2.7.0
Flask-Script==2.0.6
Flask-SQLAlchemy==2.4.1
greenlet==2.0.1
importlib-metadata==5.0.0
importlib-resources==5.10.0
itsdangerous==1.1.0
Jinja2==2.11.3
Mako==1.2.4
MarkupSafe==2.0.1
PyMySQL==1.0.2
SQLAlchemy==1.3.0
typing_extensions==4.4.0
Werkzeug==1.0.1
zipp==3.10.0
Flask-RESTful==0.3.9
PyJWT==2.7.0
websocket-client==1.5.1
gevent==22.10.1
gevent-websocket==0.10.1
Flask-Caching==2.0.2
redis==4.5.5
二、配置token認(rèn)證和解析
authen/token.py
from flask import request,g
import jwt
import time
from flask import jsonify
from functools import wraps #類裝飾器
#導(dǎo)入用戶表:這個(gè)根據(jù)用戶自己來(lái)
from apps.user.models import UserModel
JWT_SECRET_KEY = '$#%^&&*(DFHJKUTYGHF112312' #加密的鹽
ALGORITHM = 'HS256' #加密算法
#生成token
def jwt_encode_token(user_id:int,time_out=7*24*60*60):
payload = {
'user_id': user_id,
'iat': time.time(), #產(chǎn)生token時(shí)的時(shí)間戳
'exp': time.time() + time_out #token過(guò)期時(shí)間戳
}
token = jwt.encode(payload, JWT_SECRET_KEY, algorithm=ALGORITHM)
return token
#解析token
def jwt_decode_token(token):
secret = JWT_SECRET_KEY
payload = jwt.decode(token,secret,algorithms=ALGORITHM)
return payload
#類裝飾器:需要認(rèn)證
def login_required(func):
@wraps(func)
def wrapper(*args, **kwargs):
token = request.cookies.get('token', "none")
if not token:
token = request.headers.get('token', "none")
try:
payload = jwt_decode_token(token)
except Exception as e:
return jsonify({'code': 410, 'error': 'token有問(wèn)題'}),403
user_id = payload.get('user_id')
exp = payload.get('exp')
now = time.time()
obj = UserModel.query.filter_by(id=user_id).first()
if not obj:
return jsonify({'code': 410, 'error': 'token有問(wèn)題'}),403
if exp < now:
return jsonify({'code': 410, 'error': 'token已經(jīng)過(guò)期了'}),403
g.user = obj
#認(rèn)證通過(guò),執(zhí)行視圖函數(shù)
return func(*args,**kwargs)
return wrapper
def authen_admin_required(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not hasattr(g,'user'):
return jsonify({'code':410,'msg':'請(qǐng)先登錄'})
if g.user.role != '管理員':
return jsonify({'code': 410, 'msg': '沒(méi)有管理員權(quán)限,無(wú)法操作'}), 403
# 認(rèn)證通過(guò),執(zhí)行視圖函數(shù)
return func(*args, **kwargs)
return wrapper
if __name__ == '__main__':
token = jwt_encode_token(78)
三、視圖類使用
user/views.py
from flask.views import MethodView
from flask import jsonify
from flask import request,g
from ext import db
#模型類
from . import models
#認(rèn)證相關(guān)的
from authen.token import jwt_encode_token,login_required,admin_required,authen_admin_required
class RoleView(MethodView):
#所有視圖函數(shù)都需要登錄認(rèn)證
decorators=[login_required]
def get(self):
objs = models.RoleModel.query.all()
lis = []
for obj in objs:
lis.append({'id':obj.id,'name':obj.name})
return jsonify({'code':200,'data':lis})
#post請(qǐng)求需要有管理員權(quán)限
@authen_admin_required
def post(self):
print(g.user)
name = request.form.get('name')
if not name:
return jsonify({'code':400,'error':'請(qǐng)攜帶上權(quán)限名'})
obj = models.RoleModel.query.filter_by(name=name).first()
if obj:
return jsonify({'code':400,'error':f'{name} 權(quán)限已經(jīng)存在了'})
else:
obj = models.RoleModel()
obj.name=name
db.session.add(obj)
db.session.commit()
return jsonify({'code':200,'msg':f'新增角色:{name} 成功'})
認(rèn)證大致的邏輯:
1、用戶登錄時(shí),生成token,前端保存token信息
2、前端發(fā)起請(qǐng)求時(shí),將token攜帶在cookies或請(qǐng)求頭中
3、后端拿到token,先解析出token的用戶信息,將用戶信息存到g對(duì)象中
4、認(rèn)證通過(guò)后,就可以在請(qǐng)求函數(shù)中通過(guò)g獲取到當(dāng)前登錄的用戶。
管理員權(quán)限認(rèn)證的邏輯:
1、依賴于登錄認(rèn)證的流程,
2、在進(jìn)入視圖函數(shù)前,先檢驗(yàn)是否通過(guò)登錄認(rèn)證了
3、登錄認(rèn)證通過(guò)了,就可以通過(guò)g獲取當(dāng)前登錄的用戶信息文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-487572.html
4、再對(duì)登錄的用戶的信息進(jìn)行權(quán)限的判斷文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-487572.html
到了這里,關(guān)于flask框架-認(rèn)證權(quán)限(一):使用g對(duì)象存登錄用戶信息,認(rèn)證權(quán)限一起實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!