我使用的是 Expo SDK 48,我的应用程序使用基于 Web 浏览器的身份验证方案与 Google 和 Facebook 身份验证运行良好。
工作代码:
type AuthResponse = AuthSession.AuthSessionResult & {
params: {
access_token?: string;
error?: string;
};
type: string;
}
...
const AuthProvider = ({ children }: any) => {
/* Google */
const signInWithGoogle = async (navigation: any) => {
try {
const SCOPE = encodeURI("email profile");
const RESPONSE_TYPE = 'token';
const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_WEB_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=${RESPONSE_TYPE}&scope=${SCOPE}`;
const { type, params } = await AuthSession.startAsync({ authUrl }) as AuthResponse;
console.log("type ==>> " + type);
console.log("params ==>> " + JSON.stringify(params));
if (type === 'success') {
checkGoogleUserInfo(params.access_token, navigation);
} else {
return;
}
} catch (error) {
console.log("Error retrieving token data from Google ==>> ", error);
}
}
}
Expo 升级到 SDK 50 以及
expo-auth-session
升级到 5.4.0
后,AuthSession.startAsync()
停止工作。
我正在尝试使用 docs 中的新方法并遵循 this example 但在尝试从下面的代码中的 url 获取时遇到以下错误:
Possible unhandled promise rejection: SyntaxError: JSON Parse error: Unexpected character: <
无效代码:
const endpoint = "https://accounts.google.com/o/oauth2/v2/auth";
const clientId: any = GOOGLE_WEB_CLIENT_ID;
const redirectUri: any = REDIRECT_URI;
const [discovery, setDiscovery] = useState({});
useEffect(() => {
async function loadDiscovery() {
// here is the issue causing promise rejection
const getDiscovery = await fetchDiscoveryAsync(endpoint).then((discovery) => setDiscovery({ discovery }));
// nothing is displayed in console
console.log("get getDiscovery >>>>>> " + JSON.stringify(getDiscovery));
}
loadDiscovery();
}, []);
const [request, response, promptAsync] = useAuthRequest({ clientId, scopes: ['email', 'profile'], redirectUri }, discovery);
useEffect(() => {
console.log(discovery);
if (!discovery) {
console.log("no discovery");
return;
}
if (response?.type === "error") {
console.log("response type error: " + (response.params.error || "something went wrong"))
return
}
if (!discovery || (response?.type !== "success")) {
console.log("no discovery and no response type");
return;
}
const code = response.params.code;
if (!code) {
console.log("no code");
return;
}
}, [response, discovery]);
是否仍然可以使用基于网络浏览器的 Google 和 Facebook 身份验证?
编辑:
我最终使用
discovery
作为端点得到了 https://accounts.google.com
,结果是下面的 json。但我的response
仍然是null
。
{
"discovery": {
"discoveryDocument": {
"issuer": "https://accounts.google.com",
"authorization_endpoint":
"https://accounts.google.com/o/oauth2/v2/auth",
"device_authorization_endpoint":
"https://oauth2.googleapis.com/device/code",
"token_endpoint": "https://oauth2.googleapis.com/token",
"userinfo_endpoint":
"https://openidconnect.googleapis.com/v1/userinfo",
"revocation_endpoint": "https://oauth2.googleapis.com/revoke",
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token",
"none"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"email",
"profile"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
],
"claims_supported": [
"aud",
"email",
"email_verified",
"exp",
"family_name",
"given_name",
"iat",
"iss",
"locale",
"name",
"picture",
"sub"
],
"code_challenge_methods_supported": [
"plain",
"S256"
],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code",
"urn:ietf:params:oauth:grant-type:jwt-bearer"
]
},
"authorizationEndpoint":
"https://accounts.google.com/o/oauth2/v2/auth",
"tokenEndpoint": "https://oauth2.googleapis.com/token",
"revocationEndpoint": "https://oauth2.googleapis.com/revoke",
"userInfoEndpoint":
"https://openidconnect.googleapis.com/v1/userinfo"
}
}
如何使用这个发现文档?在用户输入其凭据后,我尝试从 Google 获取用户电子邮件,因为它在 SDK 更改之前正常工作。
当我终于找到Google的发现文档链接并使用Uber身份验证示例后,我可以打开网络浏览器身份验证来输入Google的凭据:
const discovery = {
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
tokenEndpoint: 'https://oauth2.googleapis.com/token',
revocationEndpoint: 'https://oauth2.googleapis.com/revoke'
};
const AuthProvider = ({ children }: any) => {
const [request, response, promptAsync] = useAuthRequest({
clientId,
scopes: ['email', 'profile'],
redirectUri,
responseType: 'code',
},
discovery
);
useEffect(() => {
console.log("request >>>>>>>>>>>>>>>>>> " + JSON.stringify(request));
console.log("response >>>>>>>>>>>>>>>>>> " + JSON.stringify(response));
console.log("discovery >>>>>>>>>>>>>>>>>> " + JSON.stringify(discovery));
}, [response]);
...
/* Google */
const signInWithGoogle = async (navigation: any) => {
try {
promptAsync();
} catch (error) {
console.log("Error retrieving token data from Google ==>> ", error);
}
}
输入 Google 帐户登录后仍然遇到错误:
Something went wrong trying to finish signing in
但我认为这应该在另一个问题上讨论。