pythonFastapiOAuth2中的password流
简单絮叨一些
前面一篇文章唠了依赖项,今天主要唠下安全性。
更多的就是身份认证或者授权等问题,一听这词就感觉很复杂, fastapi 提供了专门处理安全性的工具
安全性
使用密码和 Bearer 的简单 OAuth2
此处使用的是OAuth2 中的password 流
password流 是 OAuth2 中定义的一种方式(流),用于处理安全和身份验证。
OAuth2 指在使后端或 API 可以独立于对用户进行身份验证的服务器。
鉴于这个鬼玩意比较生疏,针对代码一段一段且一步一步的唠:fake_users_db 是定义了一个字典,就可以直接理解为是伪数据库,因为这些后期都是从数据库获取的fake_users_db = { "johndoe": { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", "hashed_password": "fakehashedsecret", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Wonderson", "email": "alice@example.com", "hashed_password": "fakehashedsecret2", "disabled": True, }, } 这个就是new 一个对象,不再多叙述app = FastAPI() fake_hash_password(password: str): 函数实际功能就是获取到字符串,然后进行拼接后再返回def fake_hash_password(password: str): return "fakehashed" + password oauth2_scheme=OAuth2PasswordBearer(tokenUrl="token") 就是new 一个对象。而OAuth2PasswordBearer 类是继承OAuth2 规范的密码流获取令牌oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") 创建的模型,它是继承基类BaseModel class User(BaseModel): username: str email: Optional[str] = None full_name: Optional[str] = None disabled: Optional[bool] = None 创建的模型,区别就是它继承的是User 类class UserInDB(User): hashed_password: str get_user(db, username: str): 函数的位置参数是,db 是数据库,而username 是指定用户的获取数据,实现功能就是,如果username 在db 中,就返回获取的数据信息,如果不在就直接返回None 。单独运行下该函数:fake_users_db = { "johndoe": { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", "hashed_password": "fakehashedsecret", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Wonderson", "email": "alice@example.com", "hashed_password": "fakehashedsecret2", "disabled": True, }, } def get_user(db, username: str): if username in db: user_dict = db[username] return UserInDB(**user_dict) print(get_user(fake_users_db, "johndoe"))
运行结果E:venvPythonScriptspython.exe E:/git_code/python-code/fastapiProject/safety_main.py username="johndoe" email="johndoe@example.com" full_name="John Doe" disabled=False hashed_password="fakehashedsecret" Process finished with exit code 0 fake_decode_token(token): 实际就是实现了调用get_user 函数的操作def fake_decode_token(token): user = get_user(fake_users_db, token) return user login 接口:@app.post("/token") def login(form_data: OAuth2PasswordRequestForm = Depends()): user_dict = fake_users_db.get(form_data.username) if not user_dict: raise HTTPException(status_code=400, detail="3333333") user = UserInDB(**user_dict) hashed_password = fake_hash_password(form_data.password) if not hashed_password == user.hashed_password: raise HTTPException(status_code=400, detail="444444") return {"access_token": user.username, "token_type": "bearer"} form_data: OAuth2PasswordRequestForm=Depends() 声明依赖。因为OAuth2 规范必须是请求表单,而OAuth2PasswordRequestForm 是Fastapi 提供的表单请求fake_users_db.get(form_data.username) 是根据表单传的username 去到fake_users_db 字典中获取用户数据并赋值给user_dict if not user_dict: 判断如果是空,则抛出异常UserInDB(**user_dict) 是Pydantic 提供的一个解包方法,解包成功后并赋值给user 。例子如下:from typing import Optional from pydantic import BaseModel class User(BaseModel): username: str email: Optional[str] = None full_name: Optional[str] = None disabled: Optional[bool] = None hashed_password: str user_dict = {"username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", "hashed_password": "fakehashedsecret", "disabled": False} user = User(**user_dict) print(user)
运行结果E:venvPythonScriptspython.exe E:/git_code/python-code/fastapiProject/hash_oauth_main.py username="johndoe" email="johndoe@example.com" full_name="John Doe" disabled=False hashed_password="fakehashedsecret" Process finished with exit code 0 以**user_dict 方式传给User ,Python 将对其进行「解包」。它会将 user_dict 的键和值作为关键字参数直接传递。hashed_password=fake_hash_password(form_data.password) 获取到输入的密码,然后传给fake_hash_password 函数,返回拼接的额密码if not hashed_password==user.hashed_password: 判断输入拼接的密码和fake_users_db 字典中指定用户的密码是否相等,如不相等就抛出异常return {"access_token": user.username, "token_type": "bearer"} 返回登录用户的信息
10.get_current_user(token: str = Depends(oauth2_scheme)): 函数,先声明依赖,其功能是根据调用fake_decode_token 函数获取用户信息,判断如果user 存在就返回信息,否则就抛出异常def get_current_user(token: str = Depends(oauth2_scheme)): user = fake_decode_token(token) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="333333", headers={"WWW-Authenticate": "Bearer"}, ) return user
11.get_current_active_user(current_user: User = Depends(get_current_user)): 函数,先声明依赖,其主要功能是如果current_user 中的disabled 为True 就抛出异常,为False 就返回用户信息def get_current_active_user(current_user: User = Depends(get_current_user)): if current_user.disabled: raise HTTPException(status_code=400, detail="33333") return current_user
12.read_item 接口:@app.get("/user/me") def read_item(current: User = Depends(get_current_active_user)): return current current: User = Depends(get_current_active_user) 声明一个依赖,然后直接返回用户数据信息
代码汇总如下:import uvicorn from fastapi import FastAPI from fastapi import Depends from pydantic import BaseModel from typing import Optional from fastapi import HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm fake_users_db = { "johndoe": { "username": "johndoe", "full_name": "John Doe", "email": "johndoe@example.com", "hashed_password": "fakehashedsecret", "disabled": False, }, "alice": { "username": "alice", "full_name": "Alice Wonderson", "email": "alice@example.com", "hashed_password": "fakehashedsecret2", "disabled": True, }, } app = FastAPI() def fake_hash_password(password: str): return "fakehashed" + password oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") class User(BaseModel): username: str email: Optional[str] = None full_name: Optional[str] = None disabled: Optional[bool] = None class UserInDB(User): hashed_password: str def get_user(db, username: str): if username in db: user_dict = db[username] return UserInDB(**user_dict) def fake_decode_token(token): user = get_user(fake_users_db, token) return user def get_current_user(token: str = Depends(oauth2_scheme)): user = fake_decode_token(token) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="333333", headers={"WWW-Authenticate": "Bearer"}, ) return user def get_current_active_user(current_user: User = Depends(get_current_user)): if current_user.disabled: raise HTTPException(status_code=400, detail="33333") return current_user @app.post("/token") def login(form_data: OAuth2PasswordRequestForm = Depends()): user_dict = fake_users_db.get(form_data.username) if not user_dict: raise HTTPException(status_code=400, detail="3333333") user = UserInDB(**user_dict) hashed_password = fake_hash_password(form_data.password) if not hashed_password == user.hashed_password: raise HTTPException(status_code=400, detail="444444") return {"access_token": user.username, "token_type": "bearer"} @app.get("/user/me") def read_item(current: User = Depends(get_current_active_user)): return current if __name__ == "__main__": uvicorn.run(app="safety_main:app", reload=True, debug=True)
运行结果截图
截图
以上只是初略解读了使用密码获取令牌,后续还有一个使用哈希值的加密,靠着仅有的知识储备,如解读的有问题,还请私信留言,会及时探讨,谢谢!
今天先聊到这里吧,以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,直接私信留言会及时修正发布;非常期待你的一键 3 连【 点赞、收藏、分享 】哟,谢谢!
未完成,待续……
一直在努力,希望你也是!
微信搜索公众号:就用python
马上评开屏摇一摇逼用户看广告,很鸡贼也很滑稽澎湃特约评论员柳早现在烦人的App广告又有新变种开屏摇一摇。据网友反映,有的App开屏摇一摇过于敏感,手机稍微一晃动就进入了广告页面。看上去摇一摇把选择权交给用户,但实际上是强迫观
脑机接口之父尼科莱利斯为何离开学界,加入中国初创企业澎湃新闻记者邵文脑机接口之父米格尔尼科莱利斯(MiguelNicolelis)宣布加入中国非侵入式脑机接口公司BrainCo(强脑科技)任首席科学顾问。米格尔尼科莱利斯(Migue
三星Exynos2200正式定档,GPU超越苹果A14?性能远不如骁龙三星海外账号正式官宣,旗下新一代处理器Exynos2200明年1月11日亮相,成为继高通骁龙8Gen1联发科天玑9000后第三款4nm工艺制程旗舰芯片。从目前曝光信息看,三星Exy
俄媒美国试图粉碎的中国科技巨头正再次崛起来源环球时报今日俄罗斯网站12月29日文章,原题美国试图粉碎的中国科技巨头正再次崛起没有任何技术企业比华为更能象征并浓缩中美之争的新态势。美国动用各种手段企图摧毁华为。但华为并没接
字节腾讯网易鏖战元宇宙背后,大厂究竟在争夺什么?图片来源视觉中国文互联网江湖正当互联网商业踌躇不前,互联网大厂为了在存量中的增长挤破头皮之时,元宇宙的概念被资本点燃。先是Facebook更名Meta正式进军元宇宙,然后字节跳动收
微信为啥不封杀淘宝链接了?因为国家不允许啊猜想1。应是有合作关系2。如果封杀也不方便了用户应用。因为实力不允许啊。工信部回应屏蔽外链9月13日上午10时,国务院新闻办公室举行新闻发布会,工业和信息化部部长肖
玛奇朵新能源欢迎垂询售16。68万起尽擎购至低0首付或36期0息,5000元购车置换补贴,随车赠送充电桩尽擎用首任车主三电系统发动机变速器终身保修,5年15万公里整车质保尽擎玩基础服务尊享服务基础流量终身免费,娱乐服
华为TUP2000亿到8000亿的发动机全员有股份等于全员没股份,就是另外一种形式的大锅饭,任正非深知这个道理。即使再愿意分股分钱的华为,19万员工中也只有11万左右是持有虚拟受限股的股东,那没有股份的怎么办?用华为的话
互联网人请别再卷了笔者是生活在帝都的一枚程序员,是15年左右靠着培训机构上车的一名iOS开发者。在从业的这段时间里也参与了好几个app项目,最初的几年也搞过SDK开发(虽然只是将原有功能包装了一下)
互联网那些事(一)互联网影响了整个社会,改变了我们所有人的生活方式,大家都知道,无需多说。说说几位互联网大佬。说起互联网,首先必须说阿里巴巴,说马云。关于阿里巴巴的商业模式,经营之道,发家历史,成功
MySQLSQL为啥排序没了今天分析一个特殊的案例,非常有意思rootmysql3357。sockemployeesshowcreatetablesalaries2G1。rowTablesalaries2Cr