后端基于firebase第三方平台注册实现
前言:
目前的面向海外app或网站登陆、注册一般都会支持第三方账号如:谷歌、Facebook、苹果等,刚好firebase支持整合这几种常见的社交平台认证且提供了前后端sdk,对接起来非常方便,下面介绍简单的登陆及注册流程。
实现:
-
注册google账号进入firebase后台,创建项目
-
在项目下创建应用,根据实际情况可选,安卓、ios、web类型。
-
点击服务账号生成后端私钥文件,保存
-
简单实现一个工具类:
依赖:<dependency> <groupId>com.google.firebase</groupId> <artifactId>firebase-admin</artifactId> <version>8.1.0</version> </dependency>
package com.example.demo.utils; import com.google.auth.oauth2.GoogleCredentials; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuthException; import com.google.firebase.auth.UserRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.FileInputStream; import java.io.IOException; public class FirebaseAuthUtils { private static final Logger log = LoggerFactory.getLogger(FirebaseAuthUtils.class); static { try { FirebaseOptions options = null; FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json"); options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.fromStream(serviceAccount)) .build(); FirebaseApp.initializeApp(options); } catch (IOException e) { log.error(e.getMessage(), e); } } /** * 验证登录token * * @param idToken * @return */ public static String verifyIdToken(String idToken) { String uid = null; try { uid = FirebaseAuth.getInstance().verifyIdToken(idToken).getUid(); } catch (FirebaseAuthException e) { log.error(e.getMessage(), e); } return uid; } /** * 获取用户基本信息 * * @param uid * @return */ public static UserRecord getUserById(String uid) { UserRecord userRecord = null; try { userRecord = FirebaseAuth.getInstance().getUser(uid); } catch (FirebaseAuthException e) { log.error(e.getMessage(), e); } return userRecord; } }
-
简单画了个时序图
-
下面介绍一个请求示例:
我本地运行了一个纯前端实现的认证项目,运行后登陆在浏览器端接口请求可以看到拿到的idToken,拿到之后发现是一个jwt格式的内容,可以直接解码,但建议调用上面工具类的verifyIdToken去获取用户id,防止数据被篡改,拿到uid后校验用户是否存在
7.UserRecord类public class UserRecord implements UserInfo { private static final String PROVIDER_ID = "firebase"; private static final Map<String, String> REMOVABLE_FIELDS = ImmutableMap.of( "displayName", "DISPLAY_NAME", "photoUrl", "PHOTO_URL"); static final String CUSTOM_ATTRIBUTES = "customAttributes"; private static final int MAX_CLAIMS_PAYLOAD_SIZE = 1000; private final String uid; private final String tenantId; private final String email; private final String phoneNumber; private final boolean emailVerified; private final String displayName; private final String photoUrl; private final boolean disabled; private final ProviderUserInfo[] providers; private final long tokensValidAfterTimestamp; private final UserMetadata userMetadata; private final Map<String, Object> customClaims; }
这是sdk自带用户类,这个类的主要用途是获取用户的第三方账号信息,如邮箱、手机、头像等
注意点:
-
同一个账号绑定多个平台,如:同时绑定google、facebook账号,需要在firebase后台操作打开这个选项后可能导致UserRecord类的email字段为空,需要从providers数组内获取
-
关于头像photoUrl字段获取到的可能是缩略图,这是由于每个平台的头像地址都会带缩略参数,下面介绍一个google和facebook拿到原图的方法,替换缩略参数:
UserRecord user = FirebaseAuthUtils.getUserById(uid); // 谷歌 String path = user.getPhotoUrl().replace("s96-c", "s500-c"); // facebook String concat = registerDTO.getPhotoUrl().indexOf("?") > 0 ? "&" : "?"; path = user.getPhotoUrl()+ concat + "type=large");