谷歌登录、脸书登录、Apple 登录
终端 flutter pub add google_sign_in
登录到 firebase 控制台添加项目 spiritual-living
添加 android 应用
获取 android SHA1
进入项目目录
终端 cd android 运行 ./gradlew signingReport
下载 google-services.json,并移动到项目 andoid->app 处
android->build.gradle 添加 classpath 'com.google.gms:google-services:4.3.15'
android->app->build.gradle 添加 apply plugin: 'com.google.gms.google-services'
implementation platform('com.google.firebase:firebase-bom:32.2.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
启动 google 登录
唤起 google 登录
Future<UserCredential?> signInWithGoogle() async {
final GoogleSignInAccount? googleSignInAccount =
await GoogleSignIn().signIn();
if (googleSignInAccount == null) {
return null;
} else {
final GoogleSignInAuthentication googleAuth =
await googleSignInAccount.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
}
添加 IOS 应用填入应用 ID
下载 GoogleService-Info.plist
xcode 打开项目右键 addrunner 添加 GoogleService-Info.plist 到 runner
打开 info.plist 添加(SERVER_CLIENT_ID、REVERSED_CLIENT_ID 在 GoogleService-Info.plist 找到并替换)
<key>SERVER_CLIENT_ID</key>
<string>[YOUR SERVER CLIENT ID]</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>[REVERSED_CLIENT_ID ]</string>
</array>
</dict>
</array>
Future<UserCredential?> signInWithGoogle() async {
final GoogleSignInAccount? googleSignInAccount =
await GoogleSignIn().signIn();
if (googleSignInAccount == null) {
return null;
} else {
final GoogleSignInAuthentication googleAuth =
await googleSignInAccount.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
}
创建应用 ID
选择 Sign In with Apple
在 xcode 中打开项目,添加 Sign In with App 服务
创建服务 ID
创建完成后返回服务列表,打开刚创建的服务 ID,勾选 Sign In with Apple,并配置 Primary App ID
打开 firebase 应用,启用 apple 填入相关信息(密码 id 为 key id,p 密钥为右边下载的.p8 内容)
复制授权回调网址
填入 apple 开发网上刚建立的 services id 的重新定向 Return URLs 处
Future<UserCredential?> signInWithApple() async {
final appleProvider = AppleAuthProvider();
if (kIsWeb) {
return await FirebaseAuth.instance.signInWithPopup(appleProvider);
} else {
return await FirebaseAuth.instance.signInWithProvider(appleProvider);
}
}
android/app/build.gradle minSdkVersion 修改为 22
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "net.pericles.spiritualliving"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
填入网络、隐私
项目 > addroid > build.gradle (Module: app)添加
implementation 'com.facebook.android:facebook-login:latest.release'
dependencies {
implementation platform('com.google.firebase:firebase-bom:32.2.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.facebook.android:facebook-login:latest.release'
}
/android/app/src/main/res/values/新建 strings.xml
例如,如果您的應用程式編號為 1234,而用戶端憑證為 56789,則程式碼如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Spiritual Living</string>
<string name="facebook_app_id">1234</string>
<string name="fb_login_protocol_scheme">fb1234</string>
<string name="facebook_client_token">6789</string>
</resources>
打开文件/android/app/src/main/AndroidManifest.xml
添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
在 application 元素中,为 Facebook 添加活动,并为 Chrome 自定义选项卡添加活动和意图筛选条件
<activity android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
查询 以 Android API 30+ (Android 11+) 为目标平台的应用无法调用 Facebook 原生应用,除非声明了程序包可见性需求
<queries>
<package android:name="com.facebook.katana" />
<provider
android:authorities="com.facebook.katana.provider.PlatformProvider"
/>
</queries>
将包名称和默认类与应用关联并保存
生成发布密钥散列
网址生成:
终端 cd android 运行 ./gradlew signingReport 并复制 sha1
key 要去除冒号并选择 hex 生成
openssl 生成:
cmd 执行 keytool -exportcert -alias sign -keystore "E:\Project\FlutterProject\spiritualliving\android\app\key\sign.jks" | openssl sha1 -binary | openssl base64
firebase 启动 facebook 验证
打开 podfile 修改 platform :ios, '12.0'
使用 Facebook 注册和配置您的应用程序,添加您的 Bundle Identifier
打开 info.plist 添加如下(facebook 与 google 例子)
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fb{your-app-id}</string>
<string>com.googleusercontent.apps.{your-app-specific-url}</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>{your-app-id}</string>
<key>FacebookClientToken</key>
<string>CLIENT-TOKEN</string>
<key>FacebookDisplayName</key>
<string>{your-app-name}</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
</array>
Future<UserCredential?> signInWithFacebook() async {
final LoginResult loginResult = await FacebookAuth.instance.login();
if (loginResult.status == LoginStatus.cancelled) {
showError("用戶取消登錄");
return null;
} else if (loginResult.status == LoginStatus.failed) {
showError("驗證失敗");
return null;
} else {
final OAuthCredential facebookAuthCredential =
FacebookAuthProvider.credential(loginResult.accessToken!.token);
return FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
}
}
对应用设置 User authentication settings 一定要开启用 email 权限,否则获取不到 emial
firebase内 Authentication->sign in method 开启 twitter,并填写 twitter 应用 key 和密钥
复制回调网址,并填写到 twitter 应用内的 Callback URI
IOS 内打开 target->info->URL Schemes,并填写编码的应用 ID,编码的应用 ID 在 firebase ios 应用下可找到
Future<UserCredential> signInWithTwitter() async {
TwitterAuthProvider twitterProvider = TwitterAuthProvider();
if (kIsWeb) {
return await FirebaseAuth.instance.signInWithPopup(twitterProvider);
} else {
return await FirebaseAuth.instance.signInWithProvider(twitterProvider);
}
}
import 'dart:convert';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import '../common/serivce/api_client.dart';
import '../common/config.dart';
import '../common/utils/easy_toast.dart';
import '../common/utils/ios_dialog.dart';
import '../common/utils/storage_manage.dart';
import '../routes/app_pages.dart';
class SignInController extends GetxController
with GetSingleTickerProviderStateMixin {
StorageManage storageManage = StorageManage();
GlobalKey<FormState> formkey = GlobalKey<FormState>();
final TextEditingController nameCtl = TextEditingController();
final TextEditingController pwdCtl = TextEditingController();
RxBool isShowPassword = true.obs;
late AnimationController animationController;
@override
void onInit() {
animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2))
..repeat(reverse: true);
var loginInfo = storageManage.read(Config.loginInfo);
if (loginInfo != null) {
Map loginInfoMap = jsonDecode(loginInfo);
if (loginInfoMap['loginType'] == "normal") {
nameCtl.text = loginInfoMap['user_name'] ?? "";
pwdCtl.text = loginInfoMap['user_password'] ?? "";
}
}
isShowPassword.value = true;
super.onInit();
}
@override
void onClose() {
animationController.dispose();
super.onClose();
}
///判断登录信息是否存在,且在登录状态时直接进入webview
void checkLogin() {
var loginInfo = storageManage.read(Config.loginInfo);
if (loginInfo != null) {
Map loginInfoMap = jsonDecode(loginInfo);
if (loginInfoMap["islogin"]) {
Get.offAndToNamed(Routes.webpage);
}
}
}
///普通登錄
Future<void> normalLogin() async {
Map<String, dynamic>? loginData;
String name = nameCtl.text;
String pwd = pwdCtl.text;
loginData = {
"displayName": name,
"pwd": pwd,
"loginType": "normal",
};
//执行远程登录
remoteLogin(
data: loginData,
loginType: 'normal',
);
}
/// 第三方登录
/// loginType 登录类型
Future<void> handleSignIn({required String loginType}) async {
Map<String, dynamic>? loginData;
try {
if (loginType == "google") {
UserCredential? auth = await signInWithGoogle();
if (auth != null) {
User? user = auth.user;
if (user != null) {
googleWithSignOut();
String? displayName = user.displayName!
.replaceAll(RegExp(r'\s+'), " ")
.replaceAll(" ", "-");
String? email = user.email;
loginData = {
"displayName": displayName,
"email": email,
"loginType": loginType,
};
}
}
} else if (loginType == "facebook") {
UserCredential? auth = await signInWithFacebook();
if (auth != null) {
User? user = auth.user;
if (user != null) {
facebookWithSignOut();
String? displayName = user.displayName!
.replaceAll(RegExp(r'\s+'), " ")
.replaceAll(" ", "-");
String? email = user.email;
loginData = {
"displayName": displayName,
"email": email,
"loginType": loginType,
};
}
}
} else if (loginType == "apple") {
UserCredential? auth = await signInWithApple();
if (auth != null) {
User? user = auth.user;
if (user != null) {
String? displayName = user.displayName;
String? email = user.email;
loginData = {
"displayName": displayName,
"email": email,
"loginType": loginType,
};
}
}
} else if (loginType == "twitter") {
UserCredential? auth = await signInWithTwitter();
User? user = auth.user;
if (user != null) {
String? displayName = user.displayName;
String? email = user.email;
loginData = {
"displayName": displayName,
"email": email,
"loginType": loginType,
};
}
} else if (loginType == "normal") {
String name = nameCtl.text;
String pwd = pwdCtl.text;
loginData = {
"displayName": name,
"pwd": pwd,
"loginType": loginType,
};
}
if (loginData != null) {
//执行远程登录
remoteLogin(
data: loginData,
loginType: loginType,
);
}
} catch (e) {
if (loginType == "google") {
googleWithSignOut();
}
if (loginType == "facebook") {
googleWithSignOut();
}
showError("登錄失敗");
}
}
///远程登录,获取登录信息
void remoteLogin(
{required Map<String, dynamic> data, required String loginType}) async {
if (loginType == "normal") {
showloading("登錄中");
} else {
showloading("授權成功,登錄中");
}
ApiClient apiClient = ApiClient();
var ret = await apiClient.post(path: Config.loginUrl, data: data);
if (EasyLoading.isShow) {
EasyLoading.dismiss();
}
if (ret != null) {
Map<String, dynamic> remoteLoginRet = jsonDecode(ret);
if (remoteLoginRet["code"] == 200) {
saveRemoteInfo(remoteData: remoteLoginRet, loginType: loginType);
Get.offAndToNamed(Routes.webpage);
} else if (remoteLoginRet["code"] == 202) {
//只有普通註冊時,賬號不存在才返回202
iosDialog(
context: Get.context!,
content: "賬號不存在,是否繼續註冊",
confirm: () {
Get.back(); //關閉對話框
showloading("註冊中"); //彈出對話框
if (!data.containsKey("isContinue")) {
data.putIfAbsent("isContinue", () => true); //添加繼續註冊標識,後台識別
}
remoteLogin(data: data, loginType: "normal"); //再次調用遠程登錄
});
} else {
if (loginType == "google") {
googleWithSignOut();
}
showError("登錄失敗");
}
} else {
if (loginType == "google") {
googleWithSignOut();
}
if (loginType == "facebook") {
googleWithSignOut();
}
showError("登錄失敗");
}
}
///保存远程信息
void saveRemoteInfo({required Map remoteData, required String loginType}) {
//print(remoteData);
final String cookieName = "wordpress_logged_in_${remoteData["cookieHash"]}";
final String cookieValue = remoteData["cookieValue"];
final int userID = remoteData["userID"];
var loginInfo = {
"loginType": loginType,
"cookieName": cookieName,
"cookieValue": cookieValue,
"userID": userID,
"islogin": true,
};
if (loginType == "normal") {
//如果是普通登录,存入用户名与密码
loginInfo.putIfAbsent("user_name", () => nameCtl.text);
loginInfo.putIfAbsent("user_password", () => pwdCtl.text);
}
storageManage.delete(Config.loginInfo);
storageManage.save(Config.loginInfo, jsonEncode(loginInfo));
}
///google登录,并将信息存储在firebase
Future<UserCredential?> signInWithGoogle() async {
final GoogleSignInAccount? googleSignInAccount =
await GoogleSignIn().signIn();
if (googleSignInAccount == null) {
return null;
} else {
final GoogleSignInAuthentication googleAuth =
await googleSignInAccount.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
}
/// facebook登錄
Future<UserCredential?> signInWithFacebook() async {
final LoginResult loginResult = await FacebookAuth.instance.login();
//print("===========>${loginResult.status}");
if (loginResult.status == LoginStatus.cancelled) {
showError("用戶取消登錄");
return null;
} else if (loginResult.status == LoginStatus.failed) {
showError("驗證失敗");
return null;
} else {
final OAuthCredential facebookAuthCredential =
FacebookAuthProvider.credential(loginResult.accessToken!.token);
return FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
}
}
///推特登录
Future<UserCredential> signInWithTwitter() async {
TwitterAuthProvider twitterProvider = TwitterAuthProvider();
if (kIsWeb) {
return await FirebaseAuth.instance.signInWithPopup(twitterProvider);
} else {
return await FirebaseAuth.instance.signInWithProvider(twitterProvider);
}
}
/// apple登錄
Future<UserCredential?> signInWithApple() async {
final appleProvider = AppleAuthProvider();
if (kIsWeb) {
return await FirebaseAuth.instance.signInWithPopup(appleProvider);
} else {
return await FirebaseAuth.instance.signInWithProvider(appleProvider);
}
}
///退出google登录
Future<GoogleSignInAccount?> googleWithSignOut() async {
try {
final GoogleSignIn googleSignIn = GoogleSignIn();
return await googleSignIn.signOut();
} catch (e) {
return null;
}
}
///退出facebook
Future<void> facebookWithSignOut() async {
try {
final FacebookAuth facebookAuth = FacebookAuth.instance;
return await facebookAuth.logOut();
} catch (e) {
return;
}
}
}
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:get/get.dart';
import '../common/config.dart';
import '../common/style/style.dart';
import '../common/utils/form_help.dart';
import '../controller/sign_in_controller.dart';
class SignIn extends StatelessWidget {
SignIn({super.key});
final signInCtl = Get.find<SignInController>();
@override
Widget build(BuildContext context) {
// WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
// signInCtl.checkLogin();
// });
final paddingTop = MediaQuery.of(context).padding.top;
return Scaffold(
resizeToAvoidBottomInset: true,
body: Container(
padding: EdgeInsets.only(
top: paddingTop,
left: Get.width * 0.08,
right: Get.width * 0.08,
),
decoration: boxLinear,
width: double.infinity,
height: double.infinity,
child: Form(
key: signInCtl.formkey,
child: SingleChildScrollView(
child: Column(
children: [
SlideTransition(
position: Tween(begin: Offset.zero, end: const Offset(0, .1))
.chain(CurveTween(curve: Curves.linear))
.animate(signInCtl.animationController),
child: Container(
constraints: const BoxConstraints(maxHeight: 200.0),
child: Image.asset("assets/splash.png")),
),
const SizedBox(
height: 20,
),
AnimationLimiter(
child: Column(
children: AnimationConfiguration.toStaggeredList(
duration: const Duration(milliseconds: 375),
childAnimationBuilder: (widget) => SlideAnimation(
horizontalOffset: MediaQuery.of(context).size.width / 2,
child: FadeInAnimation(child: widget),
),
children: [
///用戶名或郵箱
FormHelper.textInput(
controller: signInCtl.nameCtl,
labelText: "用戶名或郵箱",
icon: Icons.person,
keyboardType: TextInputType.visiblePassword,
validator: (value) {
if (value!.isEmpty) {
return "用戶名或郵箱不能為空";
}
return null;
},
),
SizedBox(height: Config.space),
///密码
Obx(() => FormHelper.textInput(
controller: signInCtl.pwdCtl,
icon: Icons.lock_outline,
labelText: "密碼",
keyboardType: TextInputType.visiblePassword,
validator: (value) {
if (value!.isEmpty) {
return '密碼不能為空';
}
return null;
},
obscureText: signInCtl.isShowPassword.value,
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: IconButton(
color: Colors.white70,
icon: signInCtl.isShowPassword.value
? const Icon(Icons.visibility)
: const Icon(Icons.visibility_off),
onPressed: () {
signInCtl.isShowPassword.value =
!signInCtl.isShowPassword.value;
},
),
))),
SizedBox(height: Config.space),
///普通登录
FormHelper.submitUIButton(
context,
title: "賬號密碼登錄",
icon: const Icon(Icons.email),
textColor: Colors.black87,
//color: Colors.grey[600],
onTap: () {
FocusScope.of(context).unfocus();
var currentState = signInCtl.formkey.currentState;
if (currentState!.validate()) {
signInCtl.handleSignIn(loginType: "normal");
}
},
),
///谷歌登录
FormHelper.submitUIButton(
context,
title: "Google登錄",
icon: ColorFiltered(
colorFilter: const ColorFilter.mode(
Colors.white, BlendMode.modulate),
child: ClipRRect(
borderRadius: BorderRadius.circular(28),
clipBehavior: Clip.antiAlias,
child: const Image(
image: AssetImage("assets/google.png"),
height: 30.0,
width: 30.0,
),
),
),
color: const Color.fromARGB(66, 18, 7, 170),
onTap: () async {
signInCtl.handleSignIn(loginType: "google");
},
),
///脸书登录
FormHelper.submitUIButton(
context,
title: "Facebook登錄",
icon: ColorFiltered(
colorFilter: const ColorFilter.mode(
Colors.white, BlendMode.srcIn),
child: ClipRRect(
borderRadius: BorderRadius.circular(28),
clipBehavior: Clip.antiAlias,
child: const Image(
image: AssetImage("assets/facebook.png"),
height: 30.0,
width: 30.0,
),
),
),
color: const Color.fromARGB(255, 52, 6, 138),
onTap: () async {
signInCtl.handleSignIn(loginType: "facebook");
},
),
///IOS Apple ID登录
FormHelper.submitUIButton(
context,
title: "Apple登錄",
icon: ColorFiltered(
colorFilter: const ColorFilter.mode(
Colors.white, BlendMode.srcIn),
child: ClipRRect(
borderRadius: BorderRadius.circular(28),
clipBehavior: Clip.hardEdge,
child: const Image(
image: AssetImage("assets/apple.png"),
height: 30.0,
width: 30.0,
),
),
),
color: Colors.black87,
onTap: () async {
signInCtl.handleSignIn(loginType: "apple");
},
),
FormHelper.submitUIButton(
context,
title: "Twitter登錄",
icon: ColorFiltered(
colorFilter: const ColorFilter.mode(
Colors.white, BlendMode.srcIn),
child: ClipRRect(
borderRadius: BorderRadius.circular(28),
clipBehavior: Clip.hardEdge,
child: const Image(
image: AssetImage("assets/twitter.png"),
height: 30.0,
width: 30.0,
),
),
),
color: const Color(0xFF00aced),
onTap: () async {
signInCtl.handleSignIn(loginType: "twitter");
},
),
],
),
),
),
],
),
),
),
),
);
}
}
<?php
error_reporting(0);
//引入WP加载文件
require '../wp-load.php';
header('Content-type:text/html;charset=utf-8');
//允许跨域
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE');
header('Access-Control-Allow-Credentials: true');
header(
'Access-Control-Allow-Headers: Content-Type,Content-Length,Accept-Encoding,X-Requested-with, Origin'
);
global $wpdb;
// 检测isActive 在user表中是否存在
$users_fields = $wpdb->get_results('SHOW FIELDS FROM wp_users;');
$field_column = array_column($users_fields, 'Field');
if (!in_array('isActive', $field_column)) {
$wpdb->query(
"ALTER table wp_users add column isActive tinyint default 1 COMMENT '1:enable,0:disable';"
);
}
$postDate = $_POST;
$displayName = $postDate['displayName'] ?? '';
$email = $postDate['email'] ?? '';
$pwd = $postDate['pwd'] ?? '';
$loginType = $postDate['loginType'] ?? '';
$isContinue = $postDate['isContinue'] ?? false;
$pass = wp_generate_password();
$user_ID = $postDate['userID'] ?? 0;
if ($loginType == 'delAccount') {
$wpdb->query("UPDATE wp_users set isActive = 0 where ID = $user_ID");
} elseif ($loginType == 'normal') {
$login_data['user_login'] = $displayName;
$login_data['user_password'] = $pwd;
$user_verify = wp_signon($login_data, false);
if (is_wp_error($user_verify)) {
//數據庫不存在用戶數據時
if ($isContinue) {
//前端彈出對話框,用戶選擇繼續註冊
if (filter_var($displayName, FILTER_VALIDATE_EMAIL)) {
$email = $displayName;
}
$signUpData = [
'user_login' => $displayName,
'user_pass' => $pwd,
'user_nicename' => sanitize_user($displayName, true),
'display_name' => $displayName,
'nickname' => $displayName,
'first_name' => $displayName,
'user_email' => $email,
'role' => get_option('default_role'),
];
$userID = wp_insert_user($signUpData);
if (!is_wp_error($userID)) {
echo loginData($userID);
} else {
$login_data['code'] = 201;
$login_data['msg'] = '注册并登录失败';
echo json_encode($login_data);
}
} else {
$login_data['code'] = 202;
$login_data['msg'] = '用户不存在,是否注册';
echo json_encode($login_data);
die();
}
} else {
//數據庫存在用戶數據時
$isActive = $user_verify->data->isActive; //用戶是否已注銷1使用中,0注銷狀態
$userID = $user_verify->ID;
if ($isActive == 0) {
if (!$isContinue) {
$login_data['code'] = 202;
$login_data['msg'] = '用户不存在,是否注册';
echo json_encode($login_data);
die();
} else {
$wpdb->query("UPDATE wp_users set isActive = 1 where ID = $userID");
echo loginData($userID);
die();
}
} else {
echo loginData($userID);
die();
}
}
} else {
//检查是否是apple以隐藏电子的形式登录
$obj = null;
if (stripos($email, 'privaterelay.appleid.com') !== false) {
$obj = get_user_by('login', $displayName);
} else {
$obj = get_user_by('email', $email);
}
$userID = 0;
if ($obj) {
$userID = $obj->ID;
}
if ($userID != 0) {
//用户存在时
//当登录是用第三方一键登录时
if ($loginType != 'normal') {
echo loginData($userID, $email);
}
} else {
//用户不存在时
$signUpData = [
'user_login' => $displayName,
'user_pass' => wp_generate_password(),
'user_nicename' => sanitize_user($displayName, true),
'display_name' => $displayName,
'nickname' => $displayName,
'first_name' => $displayName,
'user_email' => $email,
'role' => get_option('default_role'),
];
$userID = wp_insert_user($signUpData);
if (!is_wp_error($userID)) {
echo loginData($userID);
} else {
$login_data['code'] = 201;
$login_data['msg'] = '注册并登录失败';
echo json_encode($login_data);
}
}
}
/**
* @param int $userID
* @return string
*/
function loginData(int $userID, string $email = ''): string
{
//设置登录过期时间
if ($email != '') {
//更新email
wp_update_user(['ID' => $userID, 'user_email' => $email]);
}
$expiration =
time() +
apply_filters(
'auth_cookie_expiration',
50 * 365 * DAY_IN_SECONDS,
$userID,
true
);
//生成登录cookie值
$cookieValue = wp_generate_auth_cookie($userID, $expiration, 'logged_in');
$login_data['code'] = 200;
$login_data['msg'] = '登录成功';
$login_data['cookieHash'] = COOKIEHASH;
$login_data['cookieValue'] = $cookieValue;
$login_data['userID'] = $userID;
return json_encode($login_data);
}
//允许中文名注册
//function allowed_chinese_name($username, $raw_username, $strict)
//{
// $username = wp_strip_all_tags($raw_username);
// $username = remove_accents($username);
// $username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '', $username);
// $username = preg_replace('/&.+?;/', '', $username);
// if ($strict) {
// $username = preg_replace('|[^a-z\p{Han}0-9 _.\-@]|iu', '', $username);
// }
// $username = trim($username);
// $username = preg_replace('|\s+|', ' ', $username);
// return $username;
//}
//
//add_filter('sanitize_user', 'allowed_chinese_name', 10, 3);
本文章使用limfx的vscode插件快速发布