用 FastAPI 写求职者登录注册
用 FastAPI 写求职者登录注册这是一个仿 BOSS 直聘项目的后端模块技术栈是 FastAPI MySQL Redis 阿里云 OSS。下面按代码结构记录求职者登录注册这块怎么写。数据库表 models文件 app/models/job_seeker.py用 ORM 建表就是写一个 Python 类fromtortoise.modelsimportModelfromtortoiseimportfieldsclassJobSeeker(Model):idfields.IntField(pkTrue)mobilefields.CharField(max_length20,uniqueTrue)# 手机号不能重复passwordfields.CharField(max_length255,nullTrue)avatarfields.CharField(max_length500,nullTrue)# 存头像图片网址nicknamefields.CharField(max_length100,nullTrue)emailfields.CharField(max_length100,nullTrue)wechatfields.CharField(max_length100,nullTrue)create_timefields.DatetimeField(auto_now_addTrue)update_timefields.DatetimeField(auto_nowTrue)classMeta:tablet_job_seekeruniqueTrue 表示手机号不能重复nullTrue 表示可以为空auto_now_add 和 auto_now 让数据库自动记录注册时间和修改时间。参数校验 schemas文件 app/schemas/job_seeker.py前端传来的数据用 Pydantic 定规矩Field(…) 表示必传frompydanticimportBaseModel,FieldclassLoginMobileRequest(BaseModel):mobile:strField(...,title手机号)password:strField(...,title密码)classLoginSmsCodeRequest(BaseModel):mobile:strField(...)code:strField(...)classCreateUserRequest(BaseModel):mobile:strField(...)password:strField(...)code:strField(...)classUpdateUserRequest(BaseModel):mobile:strField(...)new_password:strField(...)code:strField(...)漏传的话 FastAPI 会自动报错不用自己处理。业务逻辑 services文件 app/services/job_seeker.py先准备两个工具importredis redis_clientredis.Redis(hostlocalhost,port6379,db6,decode_responsesTrue)importrandomdefget_random_code(length6):return.join(random.choices(1234567890,klength))手机号密码登录asyncdeflogin_by_mobile_password(req):jobseekerawaitJobSeeker.get_or_none(mobilereq.mobile)ifjobseekerisNone:raiseException(手机号不存在)ifjobseeker.password!req.password:raiseException(密码错误)access_token,refresh_tokencreate_tokens(str(jobseeker.id),jobseeker.mobile)return{jobseeker:jobseeker,access_token:access_token,refresh_token:refresh_token}这里密码是明文对比的练手可以正式项目要加密存储。发送登录验证码asyncdefsend_sms_code(mobile):jobseekerawaitJobSeeker.get_or_none(mobilemobile)ifjobseekerisNone:raiseException(手机号不存在)codeget_random_code(6)redis_client.set(fboss-api:login:sms:{mobile},code,ex120)returncode验证码存进 Redis120 秒后自动过期。return code 是为了方便测试正式项目应该调用短信服务发到手机。验证码登录asyncdeflogin_by_mobile_code(req):jobseekerawaitJobSeeker.get_or_none(mobilereq.mobile)ifjobseekerisNone:raiseException(手机号不存在)redis_coderedis_client.get(fboss-api:login:sms:{req.mobile})ifredis_codeisNone:raiseException(验证码已过期)ifredis_code!req.code:raiseException(验证码错误)access_token,refresh_tokencreate_tokens(str(jobseeker.id),jobseeker.mobile)redis_client.delete(fboss-api:login:sms:{req.mobile})return{jobseeker:jobseeker,access_token:access_token,refresh_token:refresh_token}先取 Redis 里的验证码过期或错误就报错通过后发 token 并删掉验证码。注册发注册验证码asyncdefsend_sms_code_create(mobile):codeget_random_code(6)redis_client.set(fboss-api:create:sms:{mobile},code,ex120)returncode正式建号asyncdefcreate_job(req):redis_coderedis_client.get(fboss-api:create:sms:{req.mobile})ifnotredis_code:raiseException(验证码已过期)ifredis_code!req.code:raiseException(验证码错误)ifawaitJobSeeker.get_or_none(mobilereq.mobile):raiseException(手机号已存在)new_jobseekerawaitJobSeeker.create(**dict(req))redis_client.delete(fboss-api:create:sms:{req.mobile})access_token,refresh_tokencreate_tokens(str(new_jobseeker.id),new_jobseeker.mobile)return{msg:注册成功,access_token:access_token,refresh_token:refresh_token}注册的 Redis key 用 boss-api:create:sms:登录用 boss-api:login:sms:两者分开互不干扰。JobSeeker.create(**dict(req)) 把前端参数直接变成一条新记录注册完直接发 token。忘记密码asyncdefforget_password(req):redis_coderedis_client.get(fboss-api:login:sms:{req.mobile})ifnotredis_code:raiseException(验证码已过期)ifredis_code!req.code:raiseException(验证码错误)jobseekerawaitJobSeeker.get_or_none(mobilereq.mobile)ifjobseekerisNone:raiseException(手机号不存在)jobseeker.passwordreq.new_passwordawaitjobseeker.save()# 改了一定要 save不然不会存进数据库redis_client.delete(fboss-api:login:sms:{req.mobile})return{msg:修改密码成功}上传头像asyncdefupdate_avatar(job_seeker_id,file):contentawaitfile.read()ossAliyunOSSTool()ok,resoss.upload_single_file(content,file.filename,oss_pathjob_seeker_avatar/)ifok:jobseekerawaitJobSeeker.get_or_none(idjob_seeker_id)jobseeker.avatarres[access_url]awaitjobseeker.save()returnresraiseException(上传失败)图片传到 OSSOSS 返回图片网址只把这个网址存进 avatar 字段。查看资料asyncdefget_job_seeker_info_by_id(job_seeker_id):jsawaitJobSeeker.get_or_none(idjob_seeker_id)js.nicknamef用户{js.mobile}ifjs.nicknameisNoneelsejs.nickname js.avatar默认头像网址ifjs.avatarisNoneelsejs.avatarreturnjs昵称和头像为空时给默认值。接口 apis文件 app/apis/job_seeker_api.pyservice 写好后包成接口网址job_seeker_router.post(/login_by_mobile_password)asyncdeflogin_by_mobile_password(req:LoginMobileRequest):resawaitJobSeekerService.login_by_mobile_password(req)return{code:1,message:登录成功,data:res}接口层只做三件事收参数、调 service、包成统一格式返回。返回格式 code 为 1 成功 0 失败message 是提示data 是数据。全部接口前缀 /job_seeker/login_by_mobile_password 密码登录/send_sms_code/{mobile} 发登录验证码/login_by_mobile_code 验证码登录/send_sms_code_create/{mobile} 发注册验证码/create_job 注册/forget_password 忘记密码/me 查看资料需登录/update_avatar 换头像需登录登录状态 JWT登录成功后发 token之后每次请求带上服务器验证就知道是谁。defcreate_tokens(user_id,username):payload{user_id:user_id,username:username,type:access}payload[exp]datetime.utcnow()timedelta(minutes120)access_tokenjwt.encode(payload,SECRET_KEY,algorithmHS256)rpayloadpayload.copy()rpayload[type]refreshrpayload[exp]datetime.utcnow()timedelta(days7)refresh_tokenjwt.encode(rpayload,SECRET_KEY,algorithmHS256)returnaccess_token,refresh_tokenaccess_token 有效期 2 小时每次请求都带refresh_token 有效期 7 天用来换新 token。app/core/depends.py 里从请求头取 token 并解析出 user_iddefget_job_seeker_info(authorization:strHeader(None)):ifnotauthorization:raiseException(请登录)tokenauthorization.replace(Bearer ,)payloadverify_token(token)ifpayloadisNone:raiseException(验证失败)returnpayload[user_id]需要登录的接口加 Depends(get_job_seeker_info)FastAPI 自动先验证并把 user_id 传进来job_seeker_router.get(/me)asyncdefget_me(job_seeker_idDepends(get_job_seeker_info)):jsawaitJobSeekerService.get_job_seeker_info_by_id(job_seeker_id)return{code:1,message:获取成功,data:js}统一异常处理service 里 raise 的异常由全局处理器接住转成统一返回defglobal_exception_handler(request,exc):returnJSONResponse(status_code500,content{code:0,message:str(exc)})在 main.py 注册app.add_exception_handler(Exception,global_exception_handler)小结把这块写完后端常用的建表、参数校验、分层、JWT 登录、Redis 存验证码、OSS 存图片、统一报错都接触到了。建议跟着敲一遍把遇到的报错自己解决掉。正式上线前还要注意密码加密、验证码真发短信、发码接口加限流。

相关新闻

使用Cloudflare部署CloudMail,零成本拥有专属企业域名邮箱,无需服务器

使用Cloudflare部署CloudMail,零成本拥有专属企业域名邮箱,无需服务器

大善人提供免费搭建专属企业邮箱,真的香啊

2026/7/24 4:43:28阅读更多 →
电信行业项目管理全链路数字化怎么选?一家年项目额超十亿电信企业500+项目一体化管控的选型分析

电信行业项目管理全链路数字化怎么选?一家年项目额超十亿电信企业500+项目一体化管控的选型分析

一、行业现状与数字化痛点 当前,电信领域的数字化转型正面临严峻挑战。行业整体数字化渗透率偏低,大量机构仍在使用纸质台账、Excel或分散的独立系统进行日常管理。从行业共性痛点来看,核心挑战集中在以下几个方面。 第一,数据孤岛…

2026/7/23 3:53:09阅读更多 →
Cortex-M4中断与异常处理:从NVIC原理到实战避坑指南

Cortex-M4中断与异常处理:从NVIC原理到实战避坑指南

1. 项目概述:从零开始理解Cortex-M4的异常与中断世界在嵌入式开发的江湖里,无论是驱动一个电机、响应一次按键,还是处理一次网络数据包的到达,背后都离不开一套高效、可靠的异常与中断处理机制。对于基于ARM Cortex-M4内核的微控制…

2026/7/24 6:56:58阅读更多 →
效率翻倍!5 款让我爱不释手的办公神器推荐

效率翻倍!5 款让我爱不释手的办公神器推荐

好物分享 日常工作中,总有一些软件能悄悄提升效率和幸福感。今天就来聊聊我最近高频使用、反复安利的几款办公效率软件。Everything:Windows 上的文件搜索神器,秒级定位本地文件,比系统自带搜索快几十倍。Snipaste:截图…

2026/7/24 13:23:00阅读更多 →
AI写作工具在教育领域的应用与优化策略

AI写作工具在教育领域的应用与优化策略

1. 项目概述:AI写作工具为何成为学生刚需? 最近在高校圈里,一款名为"千笔AI写作"的工具突然火了起来。作为一名长期关注教育技术发展的从业者,我注意到这个现象背后反映出的几个关键点:首先是当代大学生面临…

2026/7/24 13:23:00阅读更多 →
QwenImage与ControlNet在ComfyUI中的多模态图像生成实践

QwenImage与ControlNet在ComfyUI中的多模态图像生成实践

1. QwenImage与ControlNet技术解析 QwenImage是阿里巴巴Qwen团队推出的200亿参数规模的多模态扩散Transformer模型(MMDiT),采用Apache 2.0开源协议。这个模型在复杂文本渲染和精确图像编辑方面展现出显著优势,特别擅长处理中英双语…

2026/7/24 13:23:00阅读更多 →
深度学习在大地电磁反演中的应用与优化

深度学习在大地电磁反演中的应用与优化

1. 项目背景与核心价值大地电磁法(MT)作为地球物理勘探的重要手段,已经在地热资源勘查、油气田探测、深部构造研究等领域应用超过半个世纪。传统反演方法如Occam、NLCG等基于线性化近似,在面对复杂地质构造时往往陷入局部极值&…

2026/7/24 13:23:00阅读更多 →
AI健康科普系统:从知识过滤到个性化推荐

AI健康科普系统:从知识过滤到个性化推荐

1. 项目背景与核心价值去年夏天,我在三甲医院营养科做用户调研时发现个有趣现象:候诊区80%的年轻人都在刷短视频看健康科普,但问到具体内容时,多数人却说"刷到就信了"。这种信息过载与专业度缺失的矛盾,催生…

2026/7/24 13:23:00阅读更多 →
微软Phi-4多模态模型:中间融合技术与高效推理实践

微软Phi-4多模态模型:中间融合技术与高效推理实践

1. 微软Phi-4多模态推理模型的技术解析 微软最新开源的Phi-4-reasoning-vision-15B模型代表了当前多模态AI领域的重要突破。这个150亿参数的模型采用了创新的中间融合架构,将SigLIP-2的图像编码能力与Phi-4 Reasoning的文本推理能力有机结合。与传统的端到端多模态模…

2026/7/24 13:21:00阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 0:58:53阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 0:58:53阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 0:58:53阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:06阅读更多 →
【LeetCode 54】螺旋矩阵

【LeetCode 54】螺旋矩阵

问题描述: 解法: 1、模拟(参考自【LeetCode 54】螺旋矩阵-CSDN博客) int *spiralOrder(int **matrix, int matrixSize, int *matrixColSize, int *returnSize) {static const int dirs[4][2] {{0, 1}, {1, 0}, {0, -1}, {-1, …

2026/7/24 0:00:06阅读更多 →
2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

知春路不相信模型领先今年WAIC大会,昔日AI六小龙来了五家,分别是Kimi、阶跃星辰、Minimax、百川智能、零一万物。连放弃基模的百川和零一万物都来了,唯一缺席的竟是近几个月来风光无限的智谱。(DeepSeek一直不参加)WAI…

2026/7/24 0:00:06阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/23 22:58:43阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/23 18:58:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/23 18:58:18阅读更多 →