如何实现Django REST邮箱验证后重定向至Flutter移动端应用
解决dj-rest-auth/allauth邮件链接重定向到Flutter App并携带令牌的问题
核心思路是修改Django邮件中的认证/重置链接,替换为Flutter App可识别的URL Scheme(或通用链接),并将令牌作为URL参数传递,Flutter端捕获链接后解析令牌完成后续业务流程。以下分场景详细说明:
一、邮箱验证场景配置
方式1:直接修改全局配置
在Django的settings.py中添加以下配置,直接替换默认的验证链接:
# 允许通过GET请求完成邮箱验证(避免跳转Django页面) ACCOUNT_CONFIRM_EMAIL_ON_GET = True # 替换为你的Flutter App Scheme链接,{key}会自动替换为验证令牌 ACCOUNT_EMAIL_CONFIRMATION_URL = 'myapp://email-verify?token={key}'
这里的myapp://是你为Flutter App配置的URL Scheme,可自定义(比如yourapp://)。
方式2:自定义适配器实现灵活逻辑
如果需要更复杂的链接生成逻辑(比如添加额外参数),可以自定义Account适配器:
# 在你的app下创建adapters.py from allauth.account.adapter import DefaultAccountAdapter class CustomAccountAdapter(DefaultAccountAdapter): def send_confirmation_email(self, request, emailconfirmation): # 获取验证令牌 verify_token = emailconfirmation.key # 构造Flutter跳转链接 confirm_url = f"myapp://email-verify?token={verify_token}" # 替换邮件中的默认链接 emailconfirmation.email.confirmation_url = confirm_url # 调用父类方法发送邮件 super().send_confirmation_email(request, emailconfirmation)
然后在settings.py中指定自定义适配器:
ACCOUNT_ADAPTER = 'your_app_name.adapters.CustomAccountAdapter'
二、密码重置场景配置
方式1:修改全局重置URL
同样在settings.py中配置,替换默认的密码重置确认链接:
# {uid}和{token}会被dj-rest-auth自动替换为对应的重置参数 PASSWORD_RESET_CONFIRM_URL = 'myapp://password-reset?uid={uid}&token={token}'
方式2:自定义邮件模板
如果需要完全自定义邮件内容,可复制allauth的密码重置模板到你的项目templates/account/email/目录下,修改模板中的链接部分:
原模板中的重置链接:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
替换为Flutter Scheme链接:
myapp://password-reset?uid={{ uid }}&token={{ token }}
三、Flutter端处理跳转链接
1. 配置URL Scheme
- Android端:在
android/app/src/main/AndroidManifest.xml的<activity>标签内添加:
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 替换为你定义的Scheme --> <data android:scheme="myapp" /> </intent-filter>
- iOS端:在
ios/Runner/Info.plist中添加:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <!-- 替换为你定义的Scheme --> <string>myapp</string> </array> </dict> </array>
2. 捕获链接并解析令牌
可以使用app_links或url_launcher包监听跳转链接,示例代码(使用app_links):
import 'package:app_links/app_links.dart'; void initDeepLinkListener() async { final appLinks = AppLinks(); // 监听实时跳转链接 appLinks.uriLinkStream.listen((Uri uri) { switch (uri.path) { case '/email-verify': // 提取验证令牌 final token = uri.queryParameters['token'] ?? ''; if (token.isNotEmpty) { // 调用Django API完成邮箱验证,比如POST到/api/v1/auth/registration/verify-email/ _verifyEmail(token); } break; case '/password-reset': // 提取重置参数 final uid = uri.queryParameters['uid'] ?? ''; final token = uri.queryParameters['token'] ?? ''; if (uid.isNotEmpty && token.isNotEmpty) { // 跳转到密码重置页面,让用户输入新密码后调用重置API _navigateToPasswordResetPage(uid, token); } break; } }); }
四、注意事项
- 安全性建议:如果担心令牌在明文Scheme链接中泄露,可以先使用HTTPS链接(比如
https://your-domain.com/redirect/verify?token=xxx),通过后端服务器重定向到Flutter Scheme,避免令牌直接暴露在邮件中。 - 测试验证:测试时确保邮件中的链接能正确唤起Flutter App,模拟器/真机需配置好Scheme。
- 错误处理:Flutter端要处理令牌无效、过期的情况,调用Django API后根据返回结果给用户明确提示。
内容的提问来源于stack exchange,提问作者Wag
相关产品推荐
相关产品推荐

