Flutter Serverpod:如何通过Mailgun等服务发送验证码至应用(替代终端打印)
在Serverpod中实现验证码的短信/邮件发送(替代终端打印)
下面分邮件和短信两种方式,给出基于Mailgun、Sendgrid、通用SMTP及短信服务的具体实现方案:
一、邮件发送验证码
1. 使用Mailgun API
配置步骤
在Serverpod项目的config/config.yaml中添加Mailgun相关配置:
mailgun: apiKey: 'your_mailgun_api_key' domain: 'your_mailgun_verified_domain' fromEmail: 'verify@yourdomain.com'
代码实现
在你的认证Endpoint(比如auth_endpoint.dart)中添加发送方法:
import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:serverpod/serverpod.dart'; class AuthEndpoint extends Endpoint { Future<void> sendVerificationEmail(Session session, String email, String code) async { final config = session.serverpod.config; final apiKey = config.mailgun.apiKey; final domain = config.mailgun.domain; final fromEmail = config.mailgun.fromEmail; final url = Uri.parse('https://api.mailgun.net/v3/$domain/messages'); final response = await http.post( url, headers: { 'Authorization': 'Basic ${base64Encode(utf8.encode('api:$apiKey'))}', }, body: { 'from': fromEmail, 'to': email, 'subject': '你的账号验证码', 'text': '你的验证码是:$code,5分钟内有效,请勿泄露给他人。', }, ); if (response.statusCode != 200) { throw Exception('邮件发送失败:${response.body}'); } } }
2. 使用Sendgrid API
配置步骤
在config/config.yaml中添加Sendgrid配置:
sendgrid: apiKey: 'your_sendgrid_api_key' fromEmail: 'verify@yourdomain.com'
代码实现
import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:serverpod/serverpod.dart'; class AuthEndpoint extends Endpoint { Future<void> sendVerificationEmail(Session session, String email, String code) async { final config = session.serverpod.config; final apiKey = config.sendgrid.apiKey; final fromEmail = config.sendgrid.fromEmail; final url = Uri.parse('https://api.sendgrid.com/v3/mail/send'); final response = await http.post( url, headers: { 'Authorization': 'Bearer $apiKey', 'Content-Type': 'application/json', }, body: jsonEncode({ 'personalizations': [{'to': [{'email': email}]}], 'from': {'email': fromEmail}, 'subject': '你的账号验证码', 'content': [ {'type': 'text/plain', 'value': '你的验证码是:$code,5分钟内有效,请勿泄露给他人。'} ] }), ); if (response.statusCode != 202) { throw Exception('邮件发送失败:${response.body}'); } } }
3. 使用通用SMTP服务器
依赖配置
在Serverpod项目的pubspec.yaml中添加邮件依赖:
dependencies: mailer: ^6.1.0 smtp_server: ^6.1.0
配置步骤
在config/config.yaml中添加SMTP配置:
smtp: host: 'smtp.yourserver.com' port: 587 username: 'your_smtp_username' password: 'your_smtp_password' fromEmail: 'verify@yourdomain.com'
代码实现
import 'package:mailer/mailer.dart'; import 'package:mailer/smtp_server.dart'; import 'package:serverpod/serverpod.dart'; class AuthEndpoint extends Endpoint { Future<void> sendVerificationEmail(Session session, String email, String code) async { final config = session.serverpod.config; final smtpServer = SmtpServer( config.smtp.host, port: config.smtp.port, username: config.smtp.username, password: config.smtp.password, ); final message = Message() ..from = Address(config.smtp.fromEmail, '你的应用名称') ..recipients.add(email) ..subject = '你的账号验证码' ..text = '你的验证码是:$code,5分钟内有效,请勿泄露给他人。'; try { await send(message, smtpServer); } catch (e) { throw Exception('邮件发送失败:$e'); } } }
二、短信发送验证码(以Twilio为例)
配置步骤
在config/config.yaml中添加Twilio配置:
twilio: accountSid: 'your_twilio_account_sid' authToken: 'your_twilio_auth_token' fromPhone: '+1234567890' # 你的Twilio验证号码
代码实现
import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:serverpod/serverpod.dart'; class AuthEndpoint extends Endpoint { Future<void> sendVerificationSms(Session session, String phoneNumber, String code) async { final config = session.serverpod.config; final accountSid = config.twilio.accountSid; final authToken = config.twilio.authToken; final fromPhone = config.twilio.fromPhone; final url = Uri.parse('https://api.twilio.com/2010-04-01/Accounts/$accountSid/Messages.json'); final response = await http.post( url, headers: { 'Authorization': 'Basic ${base64Encode(utf8.encode('$accountSid:$authToken'))}', 'Content-Type': 'application/x-www-form-urlencoded', }, body: { 'From': fromPhone, 'To': phoneNumber, 'Body': '你的验证码是:$code,5分钟内有效,请勿泄露给他人。', }, ); if (response.statusCode != 201) { throw Exception('短信发送失败:${response.body}'); } } }
三、调用发送方法的示例逻辑
在生成验证码后,保存并调用发送方法:
import 'dart:math'; import 'package:serverpod/serverpod.dart'; import '../generated/protocol.dart'; class AuthEndpoint extends Endpoint { Future<String> requestVerification(Session session, String email) async { // 生成6位随机验证码 final code = (Random().nextInt(900000) + 100000).toString(); // 保存验证码到数据库(需提前定义VerificationCode模型) await VerificationCode.insert(session, VerificationCode( email: email, code: code, expiresAt: DateTime.now().add(const Duration(minutes: 5)), )); // 发送邮件验证码 await sendVerificationEmail(session, email, code); // 如需发送短信,替换为: // await sendVerificationSms(session, phoneNumber, code); return '验证码已发送'; } }
四、注意事项
- 所有敏感配置(API密钥、密码等)必须放在
config.yaml,切勿硬编码或提交到版本控制。 - 实现发送失败的重试机制或向Flutter客户端返回明确错误信息。
- 验证码必须设置过期时间,验证时检查有效性。
- 短信服务需提前完成号码验证、模板审核等平台要求的配置。
内容的提问来源于stack exchange,提问作者santhosh kumar
相关产品推荐
相关产品推荐

