简介
社交平台登录是现代移动应用的重要功能,它可以简化用户的注册和登录流程。本文将详细介绍如何在Flutter应用中集成主流社交平台的登录功能。
微信登录集成
1. 注册开发者账号
- 访问微信开放平台
- 注册开发者账号并创建应用
- 获取AppID和AppSecret
2. 添加依赖
在pubspec.yaml文件中添加依赖:
dependencies:
fluwx: ^6.0.6
3. 初始化配置
import 'package:fluwx/fluwx.dart';
class WeChatConfig {
// fluwx 4.x 起所有调用都走 Fluwx 实例,顶层函数 registerWxApi 已移除
static final fluwx = Fluwx();
static Future<void> initWxApi() async {
await fluwx.registerApi(
appId: "your_app_id",
universalLink: "your_universal_link", // iOS Universal Links
);
}
}
4. 实现登录
class WeChatLogin {
static Fluwx get _fluwx => WeChatConfig.fluwx;
static Future<void> login() async {
// 检查微信是否安装
final isInstalled = await _fluwx.isWeChatInstalled;
if (!isInstalled) {
throw Exception('请先安装微信');
}
// 发起登录:返回的只是"是否成功调起微信",code 走下面的回调
final launched = await _fluwx.authBy(
which: NormalAuth(
scope: "snsapi_userinfo",
state: "wechat_sdk_demo",
),
);
if (!launched) {
throw Exception('调起微信失败');
}
}
// 处理登录回调
static void handleLoginCallback() {
_fluwx.addSubscriber((res) {
if (res is WeChatAuthResponse) {
// 处理登录响应
print("登录结果:${res.code}");
// 拿到 code 后发给自己的服务端,用 AppSecret 换 access_token 和用户信息
}
});
}
}
Facebook登录集成
1. 创建Facebook应用
- 访问Facebook开发者平台
- 创建应用并获取应用ID
- 配置OAuth重定向URI
2. 添加依赖
dependencies:
flutter_facebook_auth: ^7.3.2
3. 平台配置
Android配置
在android/app/res/values/strings.xml中添加:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="facebook_app_id">YOUR_APP_ID</string>
<string name="fb_login_protocol_scheme">fbYOUR_APP_ID</string>
<string name="facebook_client_token">YOUR_CLIENT_TOKEN</string>
</resources>
iOS配置
在ios/Runner/Info.plist中添加:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fbYOUR_APP_ID</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>YOUR_APP_ID</string>
<key>FacebookClientToken</key>
<string>YOUR_CLIENT_TOKEN</string>
<key>FacebookDisplayName</key>
<string>YOUR_APP_NAME</string>
4. 实现登录
class FacebookLogin {
static final _instance = FacebookAuth.instance;
static Future<Map<String, dynamic>?> login() async {
try {
// 检查登录状态
final accessToken = await _instance.accessToken;
if (accessToken != null) {
return await getUserData();
}
// 发起登录
final result = await _instance.login(
permissions: ['email', 'public_profile'],
);
if (result.status == LoginStatus.success) {
return await getUserData();
}
return null;
} catch (e) {
print('Facebook登录错误: $e');
return null;
}
}
static Future<Map<String, dynamic>?> getUserData() async {
try {
return await _instance.getUserData();
} catch (e) {
print('获取用户数据错误: $e');
return null;
}
}
static Future<void> logout() async {
await _instance.logOut();
}
}
Google登录集成
1. 配置Firebase项目
- 在Firebase控制台启用Google登录
- 下载配置文件并添加到项目
2. 添加依赖
dependencies:
google_sign_in: ^7.2.0
firebase_auth: ^7.0.1
3. 实现登录
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class GoogleLogin {
static final _auth = FirebaseAuth.instance;
static Future<UserCredential?> signIn() async {
try {
// 7.x 起 GoogleSignIn 是单例,且调用前必须先 initialize 一次
await GoogleSignIn.instance.initialize();
// 发起登录流程
final googleUser = await GoogleSignIn.instance.authenticate();
// 7.x 的 authentication 是同步 getter,且只有 idToken;
// accessToken 改走 googleUser.authorizationClient 单独申请
final googleAuth = googleUser.authentication;
// 创建Firebase凭证
final credential = GoogleAuthProvider.credential(
idToken: googleAuth.idToken,
);
// 使用Firebase进行身份验证
return await _auth.signInWithCredential(credential);
} catch (e) {
print('Google登录错误: $e');
return null;
}
}
static Future<void> signOut() async {
await Future.wait([
GoogleSignIn.instance.signOut(),
_auth.signOut(),
]);
}
}
统一登录管理
1. 登录类型枚举
enum LoginType {
wechat,
facebook,
google,
}
2. 统一登录服务
class SocialLoginService {
static Future<Map<String, dynamic>?> login(LoginType type) async {
switch (type) {
case LoginType.wechat:
return await _handleWeChatLogin();
case LoginType.facebook:
return await _handleFacebookLogin();
case LoginType.google:
return await _handleGoogleLogin();
}
}
static Future<Map<String, dynamic>?> _handleWeChatLogin() async {
try {
await WeChatLogin.login();
// 处理微信登录结果
return null;
} catch (e) {
print('微信登录错误: $e');
return null;
}
}
static Future<Map<String, dynamic>?> _handleFacebookLogin() async {
return await FacebookLogin.login();
}
static Future<Map<String, dynamic>?> _handleGoogleLogin() async {
final credential = await GoogleLogin.signIn();
if (credential?.user != null) {
return {
'id': credential!.user!.uid,
'email': credential.user!.email,
'name': credential.user!.displayName,
'photo': credential.user!.photoURL,
};
}
return null;
}
}
3. 使用示例
class LoginPage extends StatelessWidget {
Future<void> _handleLogin(LoginType type) async {
try {
final userData = await SocialLoginService.login(type);
if (userData != null) {
print('登录成功: $userData');
// 处理登录成功后的逻辑
} else {
print('登录失败');
}
} catch (e) {
print('登录错误: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('社交登录')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => _handleLogin(LoginType.wechat),
child: Text('微信登录'),
),
ElevatedButton(
onPressed: () => _handleLogin(LoginType.facebook),
child: Text('Facebook登录'),
),
ElevatedButton(
onPressed: () => _handleLogin(LoginType.google),
child: Text('Google登录'),
),
],
),
),
);
}
}
注意事项
- iOS 强制要求:App 里有任何第三方登录,必须同时提供 Sign in with Apple,否则上架被拒——这是苹果审核铁律,不是”建议”
- code 换 token 走服务端:App 拿 code 调服务端,服务端用 AppSecret 换 token;AppSecret 永不进客户端(和支付同一条铁律)
- token 存 flutter_secure_storage:别放 SharedPreferences 明文——作者 freight 项目真实坑:登录态明文存 SP,退出登录时 controller 没清干净,切账号直接串数据
- 退出登录要清干净:清 token、清用户态 controller、清路由栈(Get.offAllNamed 回登录页)——三件缺一件,切账号就会串数据
实战案例
第三方登录(微信/QQ/Apple)我还没在项目里做过——我的 App 全是”手机号+验证码”或干脆无登录(工具类)。但我踩过相关的坑:在 某物流冷链项目 里,登录态存在 SharedPreferences(明文),退出登录时 GetX 的常驻 controller 没清,导致切账号后还是旧数据——这就是”登录”和”状态管理”搅在一起的典型问题。所以我的体会:第三方登录的难点不在”接 SDK”,在”登录态的生命周期管理”(token 存哪、过期怎么刷、退出怎么清干净)。SDK 按文档半天接完,状态理不清能折腾一周。iOS 上注意:只要有第三方登录,苹果强制要求加”Sign in with Apple”,否则上架被拒。参考:Flutter 官方文档相关章节。
总结
微信、Facebook、Google、Apple 登录,SDK 都是半天能接完的体力活。真正的坑在登录态的生命周期:token 存哪、过期怎么刷、退出登录时常驻的 controller 清没清干净——SDK 接完只是开始,状态理不清能折腾一周。iOS 上注意:只要有第三方登录,苹果强制要求加 Sign in with Apple,否则上架被拒。
