我正在尝试使用 Firebase 函数来实现这一点。授权部分运行良好,我的端点被调用。仍然当我尝试点击令牌端点时,我总是得到{"error":"invalid_client"}
. 下面是我的带有测试密钥的 firebase 功能:
import * as functions from 'firebase-functions';
import * as rp from "request-promise-native";
import * as buildURL from "build-url";
import * as jwt from "jsonwebtoken";
const privateKey = '-----BEGIN PRIVATE KEY-----\n' +
'MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgP8TqTrmSMJeaBZv+\n' +
'eOHFL8Y4b1jTIrb8d7FVIFR7vVOgCgYIKoZIzj0DAQehRANCAAQSqhtbJHJ0J24T\n' +
'vAxnANEY7m1yZJ/J7VTGXHGXWic/8xgvOIkhGnmdwgD/oCmIvjo/6yL1hlEx51hr\n' +
'EGErDIg1\n' +
'-----END PRIVATE KEY-----';
const home = 'eu.long1.signinwithappleexample://eu.long1.signinwithappleexample/auth';
const clientId = 'eu.long1.signinwithappleexample.android';
const keyId = 'TB943KQS2Y';
const teamId = 'DKY2FBVP6L';
const audience = 'https://appleid.apple.com';
const tokenEndpoint = 'https://appleid.apple.com/auth/token';
export const callback = functions.https.onRequest(async (request, response) => {
const data = <AuthResponse>request.body;
let params: { [key: string]: string } = {state: data.state};
if (data.error) {
response.redirect(buildURL(home, {queryParams: {...params, error: data.error}}));
} else if (!data.code) {
response.redirect(buildURL(home, {queryParams: {...params, error: 'no_code'}}));
} else {
try {
const jwtOptions = {
keyid: keyId,
algorithm: 'ES256',
issuer: teamId,
audience: audience,
subject: clientId,
expiresIn: 60
};
const clientSecret = jwt.sign({}, privateKey, jwtOptions);
const result = await rp.post(tokenEndpoint, {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
formData: {
client_id: clientId,
client_secret: clientSecret,
code: data.code,
grant_type: 'authorization_code',
redirect_uri: 'https://us-central1-flutter-sdk.cloudfunctions.net/callback'
}
});
response.redirect(buildURL(home, {queryParams: {...params, result: result.body}}));
} catch (e) {
response.redirect(buildURL(home, {queryParams: {...params, error: e.error}}));
}
}
});
interface AuthResponse {
readonly code: string | undefined
readonly id_token: string | undefined
readonly state: string
readonly user: AuthResponseUser | undefined
readonly error: string | undefined
}
interface AuthResponseUser {
readonly name: AuthResponseUserName | undefined
readonly email: string | undefined
}
interface AuthResponseUserName {
readonly firstName: string | undefined
readonly lastName: string | undefined
}
我的猜测是,不知何故,我没有正确签署 client_secret,因为每次我尝试在 jwt.io 上验证它时,它都说它的签名无效。