襄阳网站建设公司哪家好,太原网站建设优化,修改wordpress样式,做翻译兼职的网站1、短信通知处理的介绍
之前我在多篇随笔中介绍过基于.NET的《SqlSugar开发框架》中整合过短信接入的内容#xff1a;《使用阿里云的短信服务发送短信》、《基于SqlSugar的开发框架循序渐进介绍#xff08;17#xff09;-- 基于CSRedis实现缓存的处理》、《循序渐进VUEElem…1、短信通知处理的介绍之前我在多篇随笔中介绍过基于.NET的《SqlSugar开发框架》中整合过短信接入的内容《使用阿里云的短信服务发送短信》、《基于SqlSugar的开发框架循序渐进介绍17-- 基于CSRedis实现缓存的处理》、《循序渐进VUEElement 前端应用开发(32--- 手机短信动态码登陆处理》。短信通知一般用于系统的登录或者对重要数据变更的身份确认各个平台都相关的短信接口不过好像华为服务器已经不提供短信接入了阿里云还可以或者也可以找一些其他的短信服务商基本上都会提供相应的接口或者SDK对接还是很方便的。本篇随笔基于阿里云的短信接口进行对接短信通知也主要就是解决BS端 或者H5端的身份登录及密码修改、重置等重要处理的通知。对于Python开发来说基于阿里云的短信处理可以使用它的 alibabacloud_dysmsapi20170525 SDK包来进行对接虽然这个包时间上比较老好像也没有看到更新的SDK了。image使用pip 命令安装了该SDK即可。pip install alibabacloud_dysmsapi20170525我们使用阿里云API发送短信一般需要提供下面的身份信息。使用阿里云的短信服务需要注册登录自己的阿里云控制台然后进入AccessKeys的处理界面这里我们获取到AccessKey ID 和Access Key Secret两个关键信息需要用在数据签名的里面的。发送接口还需要提供下面的的一些信息包括必要的手机号码签名服务器端模板代码以及短信码等必要信息。签名一般为我们短信提示的公司名称如【广州爱奇迪】这样的字样。服务器端模板代码阿里云默认提供了一些基础模板我们可以从中选择。如下具体接口请求需要提供的JSON数据。复制代码{phone_numbers: 13800138000,sign_name: YourSignName,template_code: SMS_123456789,template_param: {code: 123456}}复制代码短信真实接收到的效果如下。2、在基于FastAPI的Python开发框架后端整合接口发送短信上面了解了短信的处理大致的内容我们就需要整合它进行短信的发送了。首先我们为了方便需要在项目的配置文件.env 中增加配置文件方便统一使用。image为了能够在多个地方使用我们对短信发送的处理进行简单的封装一下如下所示的辅助类初始化的时候提供相应的配置的参数即可。复制代码from alibabacloud_dysmsapi20170525.client import Client as Dysmsapi20170525Clientfrom alibabacloud_tea_openapi import models as open_api_modelsfrom alibabacloud_dysmsapi20170525 import models as dysmsapi_20170525_modelsfrom alibabacloud_tea_util import models as util_modelsfrom alibabacloud_tea_util.client import Client as UtilClientfrom typing import List, Dict, Anyclass SMSHelper: 阿里云短信服务工具类 def __init__(self, access_key_id: str, access_key_secret: str,sign_name: str, template_code: str, endpoint : str dysmsapi.aliyuncs.com ):初始化阿里云短信服务客户端:param access_key_id: 阿里云访问密钥 ID:param access_key_secret: 阿里云访问密钥 Secret:param endpoint: 阿里云 API 网关地址:param sign_name: 短信签名:param template_code: 短信模板代码if not access_key_id or not access_key_secret:raise ValueError(没有设置阿里云访问凭据请设置环境变量或在代码中设置)config open_api_models.Config(access_key_idaccess_key_id,access_key_secretaccess_key_secret,endpointendpoint)self.client Dysmsapi20170525Client(config)self.sign_name sign_nameself.template_code template_code复制代码初始化后就可以调用参数进行发送短信了复制代码def send_sms(self, phone_numbers: str, template_param: Dict[str, Any] None) - Dict[str, Any]:使用阿里云 SMS 服务发送短信Args:phone_numbers: 短信接收号码template_param: 短信模板参数字典形式Returns:短信发送结果字典形式# 创建 request 对象send_sms_request dysmsapi_20170525_models.SendSmsRequest(phone_numbersphone_numbers,sign_name self.sign_name,template_codeself.template_code,template_paramstr(template_param) if template_param else None)response {}try:# 发送短信result self.client.send_sms_with_options(send_sms_request, util_models.RuntimeOptions())# 转换结果为字典形式response {success: True,message: SMS 发送成功,request_id: result.body.request_id,code: result.body.code,message: result.body.message,biz_id: result.body.biz_id}except Exception as error:response {success: False,message: str(error.message) if hasattr(error, message) else str(error),recommend: error.data.get(Recommend) if hasattr(error, data) else None}return response复制代码完成了上面的简单封装就可以再API的控制器端进行短信处理了。如我们在登录login的EndPoint类似C#的控制器类中需要先初始化短信的服务辅助类。image上面也介绍过短信主要就是解决BS端 或者H5端的身份登录及密码修改、重置等重要处理的通知。我们在以手机号码和短信号码登录的时候需要先发送短信然后短信会在服务端通过Redis的缓存驻留几分钟这几分钟内容通过手机和验证码即可登录登录后验证码失效如果超时验证码也失效。通过手机号码发送短信的过程如下所示。复制代码router.post(/send-login-smscode,summary发送登录验证码,response_modelAjaxResponse[CommonResult | None],)async def send_login_smscode(input: Annotated[PhoneCaptchaModel, Body()],request: Request,db: AsyncSession Depends(get_db),):ip await get_ip(request)# 校验手机号码是否合法if not input.phonenumber.isdigit() or len(input.phonenumber) ! 11:raise CustomExceptionBase(detail手机号码格式不正确)# 校验用户是否存在user await user_crud.get_by_column(db, mobilephone, input.phonenumber)if not user:raise CustomExceptionBase(detail用户不存在)# 生成6位数字验证码code RandomUtil.random_digit_string(6)# 发送短信验证码res sms_helper.send_sms(phone_numbersinput.phonenumber,template_param{code: code},)success res.get(success, False) Truemessage res.get(message, )if success:#以手机号码作为键存储验证码缓存cache_key input.phonenumber.strip()cache_item SmsLoginCodeCacheItem(phonenumberinput.phonenumber.strip(),codecode,).model_dump()redis_helper RedisHelper(client redis_client)await redis_helper.set(cache_key, cache_item, 60 * settings.SMS_EXPIRED_MINUTES) # 默认5分钟过期# 短信验证码发送结果result CommonResult(successsuccess, errormessagemessage)return AjaxResponse(result)复制代码上面短信发送后号码机验证码会驻留在Redis的缓存中一段时间那么此时如果使用手机验证码进行登录即可匹配到。复制代码router.post(/authenticate-byphone,summary手机短信验证码登录授权处理,response_modelAjaxResponse[AuthenticateResultDto],)async def authenticate_by_phone(input: Annotated[PhoneCaptchaModel, Body()],request: Request,db: AsyncSession Depends(get_db),):ip await get_ip(request)auth_result AuthenticateResultDto(ipip, successFalse)# 从缓存中获取验证码redis_helper RedisHelper(clientredis_client)cache_key input.phonenumber.strip()if not cache_key.isdigit() or len(cache_key) ! 11:raise CustomExceptionBase(detail手机号码格式不正确)# 校验验证码是否正确if not input.smscode.isdigit() or len(input.smscode) ! 6:raise CustomExceptionBase(detail验证码格式不正确)cache_item await redis_helper.get(cache_key)if not cache_item:raise CustomExceptionBase(detail验证码已过期或不存在请重新获取)cache_item SmsLoginCodeCacheItem(**cache_item)if cache_item.code ! input.smscode:raise CustomExceptionBase(detail验证码不正确请重新输入)# 校验用户是否存在user await user_crud.get_by_column(db, mobilephone, input.phonenumber)if not user:raise CustomExceptionBase(detail用户不存在)# 验证码正确继续登录流程if cache_item and user:#获取用户角色类型auth_result.roletype await role_crud.get_user_roletype(db, user.id) # 超级管理员、系统管理员、其他# 根据用户身份生成tokenresultauth_result.expires int((datetime.utcnow() timedelta(secondssettings.TOKEN_EXPIRE_SECONDS)).timestamp())auth_result.userid user.idauth_result.name user.nameauth_result.success Trueauth_result.accesstoken await generate_token(vars(user), role_typeauth_result.roletype)#移除缓存短信键值await redis_helper.delete(cache_key)else:auth_result.error 登录失败无法生成令牌return AjaxResponse(auth_result)复制代码其他的重置密码修改密码修改重要信息等通知的处理也是类似的处理过程不在赘述。3、在基于FastAPI的Python开发框架中整合邮件发送我们通过pip命令安装fastapi_mail组件进行邮件发送的处理。pip install fastapi_mail邮件发送一般也是基于模板文件的方式通过对模板文件的变量进行变化实现内容的发送过程。我们的模板路径如下所示里面有类似下面的几个模板文件如果需要更多场合的右键可以进行不同的模板编写即可。# templates/# email/# welcome.html# reset_password.html增加一个EmailHelper.py的辅助类简单处理下方便后续的邮件发送处理。复制代码from typing import List, Optional, Dictfrom fastapi.templating import Jinja2Templatesfrom fastapi_mail import FastMail, MessageSchema, ConnectionConfig, MessageTypefrom fastapi import BackgroundTasksfrom jinja2 import Environment, FileSystemLoader, select_autoescapeclass EmailHelper: 邮件发送辅助类基于 fastapi-mail def __init__(self,username: str,password: str,mail_from: str,server: str smtp.example.com,port: int 587,use_tls: bool True,use_ssl: bool False,template_folder: str app/templates/email,enable_template_cache: bool True, # 开关是否启用模板缓存):self.conf ConnectionConfig(MAIL_USERNAMEusername,MAIL_PASSWORDpassword,MAIL_FROMmail_from,MAIL_PORTport,MAIL_SERVERserver,MAIL_SSL_TLSuse_ssl,MAIL_STARTTLSTrue if use_tls else False,USE_CREDENTIALSTrue,)self.fm FastMail(self.conf)# 模板目录# self.templates Jinja2Templates(directorytemplate_folder)# 增加 模板缓存 / 热更新开关这样在 开发环境下可以实时修改模板生效在 生产环境下则启用缓存提升性能。# Jinja2 环境self.env Environment(loaderFileSystemLoader(template_folder),autoescapeselect_autoescape([html, xml]),cache_size50 if enable_template_cache else 0, # 0 每次重新加载模板)async def send_email(self,subject: str,recipients: List[str],body: str,subtype: MessageType MessageType.plain,background_tasks: Optional[BackgroundTasks] None,attachments: Optional[List[str]] None,):发送邮件支持同步调用和后台任务:param subject: 邮件主题:param recipients: 收件人列表:param body: 邮件正文:param subtype: 内容类型plain 或 html:param background_tasks: FastAPI BackgroundTasks可选:param attachments: 附件路径列表可选message MessageSchema(subjectsubject,recipientsrecipients,bodybody,subtypesubtype,attachmentsattachments or [] # 如果是 None自动变成 [])if background_tasks:background_tasks.add_task(self.fm.send_message, message)else:await self.fm.send_message(message)async def send_template_email(self,subject: str,recipients: List[str],template_name: str,context: Dict,background_tasks: Optional[BackgroundTasks] None,attachments: Optional[List[str]] None,):发送基于 Jinja2 模板的邮件:param subject: 邮件主题:param recipients: 收件人列表:param template_name: 模板文件名 (如 welcome.html):param context: 模板变量# 渲染模板# template self.templates.get_template(template_name)template self.env.get_template(template_name)body template.render(**context)await self.send_email(subjectsubject,recipientsrecipients,bodybody,subtypeMessageType.html,background_tasksbackground_tasks,attachmentsattachments or [] # 如果是 None自动变成 [])复制代码我们在一个独立的EndPoint的类中提供邮件发送的处理API。初始化接口如下所示image两个利用邮件模板发送邮件的例子如下所示。image以上就是基于FastAPI的Python开发框架后端增加阿里云短信和邮件发送通知处理的相关实现过程希望对你有所帮助。