Flutter+python实现验证码登录
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。在界面这部分我引用了smsController类中的两个方法,在这两个方法中我调用后端接口,分别实现了发送验证码,以及验证验证码的功能。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下
实现思路
前端(Flutter应用)的工作:
-
收集用户信息:
- 用户输入手机号码,前端收集这个信息。
-
发送请求到后端:
- 当用户点击发送验证码按钮时,前端向后端发送一个包含手机号码的请求。
-
接收后端响应:
- 根据后端的响应,前端显示相应的信息给用户,比如“验证码发送成功”或“发送失败”。
-
收集验证码输入:
- 用户收到短信后,将验证码输入到前端界面。
-
提交验证码进行验证:
- 用户提交验证码后,前端将手机号码和验证码一起发送到后端进行验证。
后端的工作:
-
接收来自前端的请求:
- 后端接收来自前端的包含手机号码的请求。
-
生成验证码:
- 后端生成一个随机的验证码。
-
调用短信服务API发送验证码:
- 后端调用阿里云短信服务API,将验证码发送到用户的手机号码。
-
存储验证码:
- 后端暂时存储验证码及其相关信息(如手机号、过期时间等),以便稍后验证。
-
响应前端:
- 后端向前端发送响应,表示验证码是否发送成功。
-
接收并验证验证码:
- 当用户提交验证码时,后端接收手机号码和验证码,验证验证码的正确性。
-
返回验证结果:
- 后端返回验证结果给前端,如“验证成功”或“验证失败”。
前期准备工作
我使用的是阿里云短信服务,在调用短信API之前,要完成以下工作:
- 申请产品试用
- 在阿里云通信产品免费试用申请免费产品试用,我是个人用户,因此申请的第一个
2. 定义模板和签名
- 在短信服务中心完成模板和签名的申请。模板和签名定义了你收到短信的内容,这一步可以不进行,阿里云提供了专用的测试模板和签名,可以直接使用
3. 添加测试手机号
4. 获取AccessKey ID 和 AccessKey Secret
- 点击右上角头像,点击AccessKey管理,点击创建AccessKey按钮,创建新的AccessKey,记得保存好AccessKey ID 和 AccessKey Secret
前端代码
界面代码
class Sms extends StatefulWidget {
const Sms({super.key});
@override
State<Sms> createState() => _SmsState();
}
class _SmsState extends State<Sms> {
final TextEditingController _phoneController = TextEditingController();
final TextEditingController _codeController = TextEditingController();
bool _isButtonDisabled = true;
bool _isCodeSent = false;
int _countdown = 60;
final SmsController _smsController = SmsController();
void _updateState() {
setState(() {
_isCodeSent = true;
_startCountdown();
});
}
void _startCountdown() {
Future.delayed(Duration(seconds: 1), () {
if (_countdown > 0) {
setState(() {
_countdown--;
});
_startCountdown();
} else {
setState(() {
_isCodeSent = false;
_countdown = 60;
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('验证码登录')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'使用验证码登录',
textAlign: TextAlign.center,
style: TextStyle(fontSize: MediaQuery.of(context).size.width * 0.05),
),
SizedBox(height: 20),
Row(
children: <Widget>[
Expanded(
child: TextField(
controller: _phoneController,
decoration: InputDecoration(hintText: '输入手机号'),
keyboardType: TextInputType.phone,
),
),
TextButton(
child: _isCodeSent
? Text('重发($_countdown)')
: Text('发送验证码'),
onPressed: _isCodeSent ? null : () async {
await _smsController.sendCode(
_phoneController.text, context, _updateState);
},
),
],
),
TextField(
controller: _codeController,
decoration: InputDecoration(hintText: '输入验证码'),
onChanged: (value) {
setState(() {
_isButtonDisabled = value.isEmpty;
});
},
),
SizedBox(height: 20),
ElevatedButton(
child: Text('登录'),
onPressed: _isButtonDisabled ? null : () async {
await _smsController.verifyCodeAndLogin(
_phoneController.text, _codeController.text, context);
},
),
],
),
),
);
}
}
在界面这部分我引用了smsController类中的两个方法,在这两个方法中我调用后端接口,分别实现了发送验证码,以及验证验证码的功能。代码如下:
class SmsController {
Future<void> verifyCodeAndLogin(String phoneNumber, String code, BuildContext context) async {
final response = await http.post(
//后端接口,替换你的后端接口
Uri.parse('http://000.000.0000.000/verify_code'),
headers: <String, String>{
'Content-Type': 'application/json',
},
body: jsonEncode(<String, String>{
'phone_number': phoneNumber,
'code': code,
}),
);
if (response.statusCode == 200) {
Navigator.pushNamed(context, '/index');
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('手机号或验证码错误')),
);
}
}
Future<void> sendCode(String phoneNumber, BuildContext context, Function updateState) async {
if (phoneNumber.length == 11) {
final response = await http.post(
//后端接口,替换你的后端接口
Uri.parse('http://000.000.0000.000/send_verification_sms'),
headers: <String, String>{
'Content-Type': 'application/json',
},
body: jsonEncode(<String, String>{
'phone_number': phoneNumber,
}),
);
if (response.statusCode == 200) {
updateState();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('验证码已成功发送')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('验证码发送失败')),
);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('手机号格式错误')),
);
}
}
}
后端代码使用python实现,代码如下
@app.route('/send_verification_sms', methods=['POST'])
async def send_verification_sms():
phone_number = (await request.get_json()).get('phone_number')
if not phone_number:
return jsonify({"error": "Phone number is required"}), 400
sign_name = "阿里云短信测试" # Replace with your sign name
#输入你的模板code
template_code = ""
try:
response = send_sms(phone_number, sign_name, template_code)
return jsonify({"message": "SMS sent successfully", "response": str(response)})
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route('/verify_code', methods=['POST'])
async def verify_sms_code():
json_data = await request.get_json()
phone_number = json_data.get('phone_number')
code = json_data.get('code')
if verify_code(phone_number, code):
return jsonify({"message": "Verification successful"})
else:
return jsonify({"error": "Invalid or expired code"}), 400
#输入你的ACCESS_KEY_ID和ACCESS_KEY_SECRET
ACCESS_KEY_ID = ""
ACCESS_KEY_SECRET = ""
client = AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, 'cn-hangzhou')
def send_sms(phone_numbers, sign_name, template_code):
request = CommonRequest()
request.set_accept_format('json')
request.set_domain('dysmsapi.aliyuncs.com')
request.set_method('POST')
request.set_protocol_type('https') # https | http
request.set_version('2017-05-25')
request.set_action_name('SendSms')
request.add_query_param('RegionId', "cn-hangzhou")
request.add_query_param('PhoneNumbers', phone_numbers)
request.add_query_param('SignName', sign_name)
request.add_query_param('TemplateCode', template_code)
verification_code = generate_verification_code()
params = f"{{\"code\":\"{verification_code}\"}}"
request.add_query_param('TemplateParam', params)
# 保存验证码和时间戳
with shelve.open('verification_codes.db') as db:
db[phone_numbers] = {'code': verification_code, 'timestamp': datetime.now()}
response = client.do_action_with_exception(request)
return response
def verify_code(phone_number, code):
with shelve.open('verification_codes.db') as db:
if phone_number in db:
data = db[phone_number]
# 检查验证码是否匹配且未过期(5分钟)
if data['code'] == code and datetime.now() - data['timestamp'] <= timedelta(minutes=5):
return True
return False
本文转自 https://juejin.cn/post/7316349124599758884,如有侵权,请联系删除。
题外话
感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python兼职渠道推荐*
学的同时助你创收,每天花1-2小时兼职,轻松稿定生活费.
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
👉CSDN大礼包🎁:全网最全《Python学习资料》免费赠送🆓!(安全链接,放心点击)
若有侵权,请联系删除

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)