【问题标题】:Running into auth/operation-not-allowed in firebase auth when using a LinkedIn Provider使用 LinkedIn 提供程序时在 firebase 身份验证中遇到身份验证/操作不允许
【发布时间】:2021-05-18 20:29:45
【问题描述】:

我正在使用stack overflow 上的代码 sn-p 使用 LinkedIn 提供商登录:

export function signUpWithLinkedIn() {
    return auth
        .setPersistence(firebase.auth.Auth.Persistence.SESSION)
        .then(()=>{
            const provider = new firebase.auth.OAuthProvider('linkedin.com');
            provider.addScope('r_emailaddress');
            provider.addScope('r_liteprofile');
            auth
                .signInWithPopup(provider)
                .then(result=>{
                    console.group('LinkedIn');
                    console.log(result);
                    console.groupEnd();
                    return result;
                })
                .catch(error=>{
                    console.group('LinkedIn - Error');
                    console.log(error)
                    console.groupEnd();
                    throw error;
                });

        });
}

我收到错误“auth/operation-not-allowed”、“未找到身份提供程序配置”。遇到此错误的其他人正在使用本机支持的登录提供程序,例如 Google 或 Facebook,并在 Firebase 控制台上启用这些提供程序可避免此错误。关于如何使用 LinkedIn 完成类似任务的任何想法?

【问题讨论】:

    标签: firebase oauth firebase-authentication linkedin-api


    【解决方案1】:

    要使用自定义身份验证解决方案,需要中间服务(例如 Cloud Functions)或专用服务器来与 OAuth 提供程序进行交互。原因是 OAuth 提供者需要一个自定义 App 来代表您自己的 App 对其基础设施的要求,通常这只是 Auth 权限。此过程将为您提供一个密钥,您必须将其存储在安全环境中,以便您可以授权对您的应用的请求。

    在您的身份验证提供者的应用程序中将有一个身份验证部分,该部分将要求重定向 URL,这将用作成功登录服务器时的回调,然后将为您的客户端应用程序生成足够的令牌。

    使用 Firebase Cloud Functions 进行设置:

    1. 如果您还没有,您需要在LinkedIn Developers website 中创建一个LinkedIn 应用程序。

    2. 将 URL https://<application-id>.firebaseapp.com/popup.html 添加到您的 LinkedIn 应用的 OAuth 2.0 > 授权重定向 URL

    3. 复制您的 LinkedIn 应用的客户端 ID 和客户端密码,并使用它们来设置 linkedin.client_idlinkedin.client_secret Google Cloud 环境变量。为此,在项目中运行控制台命令,如下所示:

    firebase functions:config:set linkedin.client_id="yourClientID" linkedin.client_secret="yourClientSecret"
    

    在您的 Cloud Functions 中,您需要一个充当握手客户端的工作脚本

    我建议查看这个完整的项目,因为自定义 OAuth 解决方案涉及更多:LinkedIn with Firebase

    【讨论】:

    • 我一直在研究这个代码库。我感到困惑的一件事是“/重定向”页面的定义位置。在 popup.html 中,页面推送到一个未知路由的 '/redirect' url。
    • 它被发送到 OAuth 提供商,因此当您完成登录时,它会将用户重定向回您的站点
    • 对,但现在它正在触发我的未知路由回退。我更改了 firebase.json 以重定向路由以调用该函数,但也许是因为我正在本地主机上进行测试?我正在部署该站点。如果没有托管,firebase 功能是否无法工作?
    • 云函数不需要托管,但您可以设置从托管重写到云函数。
    【解决方案2】:

    要为您的 Firebase 项目使用 LinkedIn 登录,您首先需要以编程方式将 LinkedIn OAuth 配置为 Firebase 身份验证的身份提供者。请参阅有关如何在 Firebase 上配置 OAuth 的文档。

    对于我的项目,我遵循以下步骤:

    第 1 步: 在我的项目文件夹中创建 node.js 文件并复制粘贴 Firebase 文档提供的代码以获取对我的 Firebase 项目的访问权限:

    const googleAuth = require('google-auth-library');
    const SCOPES = ['https://www.googleapis.com/auth/cloud-platform'];
    
    async function getAccessToken() {
        const serviceAccount = require('/path/to/service_account_key.json');
        const jwtClient = new googleAuth.JWT(
            serviceAccount.client_email,
            null,
            serviceAccount.private_key,
            SCOPES,
            null
        );
        return jwtClient.authorize().then((tokens) => tokens.access_token);
    }
    

    第 2 步: 在上面的函数中,您需要通过转到 Firebase 控制台并单击项目设置 > 服务帐户来检索您的 private_key 和 client_email。将下载一个文件,您可以将其添加到安全位置。确保路径正确

    第 3 步: 转到LinkedIn并按照步骤创建一个APP。完成此操作后,您将能够获得客户 ID 和密码。在您的身份验证设置中,请将您的回调网址设置为 firebase。示例:

    Authorized redirect URLs for your app: https://your-project-id.firebaseapp.com/__/auth/handler
    

    第 4 步: 返回到您的 node.js 文件,然后将 LinkedIn 的配置代码复制粘贴到您的 getAccessFunction 下方(请参阅文档):

    const fetch = require('node-fetch');
    const GCIP_API_BASE = 'https://identitytoolkit.googleapis.com/v2';
    
    async function addIdpConfig(projectId, accessToken, idpId, clientId, clientSecret) {
        const uri = `${GCIP_API_BASE}/projects/${projectId}/defaultSupportedIdpConfigs?idpId=${idpId}`;
        const options = {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${accessToken}`
            },
            body: JSON.stringify({
                name: `projects/${projectId}/defaultSupportedIdpConfigs/${idpId}`,
                enabled: true,
                clientId: clientId,
                clientSecret: clientSecret,
            }),
        };
        return fetch(uri, options).then((response) => {
            if (response.ok) {
                return response.json();
            } else if (response.status == 409) {
                throw new Error('IdP configuration already exists. Update it instead.');
            } else {
                throw new Error('Server error.');
            }
        });
    }
    
    (async () => {
        const projectId = 'your-firebase-project-id';
        const accessToken = await getAccessToken();
        const idpId = 'linkedin.com';
        const clientId = 'your-linkedin-client-id';
        const clientSecret = 'your-linkedin-client-secret';
        try {
            await addIdpConfig(projectId, accessToken, idpId, clientId, clientSecret);
        } catch (err) {
            console.error(err.message);
        }
    })().catch(console.error);
    

    第 5 步: 在终端中运行 node.js 文件。您将收到一条消息,说明配置已添加。为确保它正常工作,您可以再次运行节点文件,并且应该会收到配置已存在的消息。

    第 6 步: 创建组件以显示 LinkedIn 按钮

    import { signUpWithLinkedIn } from "../../auth/LinkedInAuth";
    
    const LinkedInLogin = () => {
        return (
            <div onClick={() => signUpWithLinkedIn()} >
                <div type="submit" style={{ height: "40px", width: "215px" }}>
                    <img
                        style={{ height: "100%", width: "100%" }}
                        src={
                            "https://taggbox.com/blog/wp-content/uploads/2018/09/Signin-with-LinkedIn.png"
                        }
                        alt={"LinkedIn authentification"}
                    />
                </div>
            </div>
        )
    }
    
    export default LinkedInLogin
    

    第 7 步: 为 LinkedIn 创建 authAction

    import {auth, firebase} from "../../../lib/db"
    
    export function signUpWithLinkedIn() {
        return auth
        .setPersistence(firebase.auth.Auth.Persistence.SESSION)
        .then(()=>{
            const provider = new firebase.auth.OAuthProvider('linkedin.com');
            provider.addScope('r_emailaddress');
            provider.addScope('r_liteprofile');
            auth
                .signInWithPopup(provider)
                .then(result=>{
                    console.group('LinkedIn');
                    console.log(result);
                    console.groupEnd();
                    return result;
                })
                .catch(error=>{
                    console.group('LinkedIn - Error');
                    console.log(error)
                    console.groupEnd();
                    throw error;
                });
    
        }); 
    }
    

    就是这样!我有任何问题请告诉我。

    【讨论】:

      猜你喜欢
      • 2023-03-15
      • 2018-10-31
      • 2017-12-25
      • 2018-12-20
      • 2021-04-12
      • 2021-02-28
      • 1970-01-01
      • 2015-05-21
      • 2020-08-17
      相关资源
      最近更新 更多