Expo/React Native 对接Firebase后端实现Microsoft OAuth认证的问题求助
Expo/React Native 对接Firebase后端实现Microsoft OAuth认证的问题求助
我目前在基于Expo Dev Client的React Native纯JS项目(仅Android平台)中,尝试通过Firebase实现Microsoft OAuth认证,但一直卡在**「unmatched route(不匹配路由)」**的问题上:Microsoft返回的带长哈希参数的回调链接,总是被Expo的路由机制拦截报错。
我已经试过react-native-app-auth、react-native-firebase/auth,还有expo-auth-session相关方法,也有人提醒我不要使用Web SDK,毕竟是React Native原生环境。我确认重定向URI是正确的,现在核心需求就是能顺利拿到令牌并传给Firebase,麻烦各位帮忙排查下我的代码问题!
我的认证逻辑代码(MicrosoftAuthService.js)
import auth from "@react-native-firebase/auth"; import * as AuthSession from "expo-auth-session"; import * as WebBrowser from "expo-web-browser"; WebBrowser.maybeCompleteAuthSession(); export const signInWithMicrosoft = async () => { try { const discovery = await AuthSession.fetchDiscoveryAsync( "https://login.microsoftonline.com/common/v2.0", ); // 尝试用makeRedirectUri解决「unmatched route」错误 const redirectUri = AuthSession.makeRedirectUri({ scheme: "msauth", path: "com.clouddropdesigns.vibenmed/Xo8WBi6jzSxkDVR4drqm84yr9iU=", }); const request = await AuthSession.loadAsync( { clientId: "client id", redirectUri: redirectUri, scopes: ["openid", "profile", "email", "offline_access"], responseType: AuthSession.ResponseType.IdToken, extraParams: { prompt: "select_account", nonce: Math.random().toString(36).substring(7), }, }, discovery, ); const response = await request.promptAsync(discovery); if (response.type !== "success") { throw new Error("Microsoft sign-in dismissed or failed."); } const { id_token } = response.params; // 修正:Firebase RN的正确语法(凭证不需要用new关键字) const credential = auth.MicrosoftAuthProvider.credential(id_token); const userCredential = await auth().signInWithCredential(credential); return userCredential.user; } catch (error) { console.error("Login Error:", error); throw error; } };
登录按钮组件代码
import { Image, Pressable, StyleSheet } from "react-native"; import { useDispatch, useSelector } from "react-redux"; import { setError, setSignIn, setUser } from "../../../redux/slices/auth.slice"; import { signInWithMicrosoft } from "../util/MicrosoftAuthService"; const MICROSOFT_LOGO = require("./ms-symbollockup_signin_dark.png"); const MicrosoftLoginButton = () => { const dispatch = useDispatch(); const { user, signIn } = useSelector((state) => state.auth); const handleSignIn = async () => { try { const user = await signInWithMicrosoft(); if (user) { dispatch(setSignIn(true)); dispatch(setUser(user.uid)); // 现在直接返回用户对象 } } catch (error) { dispatch(setError(error.message)); } }; return ( <Pressable style={styles.btn} onPress={handleSignIn} accessibilityRole="button" accessibilityLabel="Sign in with Microsoft" accessibilityHint="Signs in to Med Alliance using Microsoft Account" > <Image source={MICROSOFT_LOGO} style={styles.img} resizeMode="contain" /> </Pressable> ); }; export default MicrosoftLoginButton; const styles = StyleSheet.create({ btn: { width: 248, height: 48, justifyContent: "center", alignItems: "center", marginTop: 24, }, img: { width: "100%", height: "100%", }, });
备注:内容来源于stack exchange,提问作者cloudp7
相关产品推荐
相关产品推荐

