简体   繁体   English

将Google身份验证添加到Firebase实时数据库

[英]Add Google authentication to Firebase Real Time Database

I'm using the Firebase Real Time Database and I need to add user authentication to it. 我正在使用Firebase实时数据库,我需要为其添加用户身份验证。 Users can only login with Google as a provider. 用户只能使用Google作为提供商登录。

Current database mode: 当前数据库模式:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

New mode should be like this: 模式应该是这样的:

// These rules grant access to a node matching the authenticated
// user's ID from the Firebase auth token
{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

What should I use to authenticate in my case? 在我的情况下,我应该使用什么来进行身份验证? userID , Google providerID or a token like described here ? userID ,Google providerID此处描述令牌

This is the function without authentication to store data: 这是没有身份验证的功能来存储数据:

 createMeetup ({commit, getters}, payload) {
      console.log('index.js -> createMeetup')
      const meetup = {
        title: payload.title,
      }
      let imageUrl
      let key
      firebase.database().ref('meetups').push(meetup)
        .then((data) => {
          key = data.key
          return key
        })
        .then(() => {
          commit('createMeetup', {
            ...meetup,
            imageUrl: imageUrl,
            id: key
          })
        })
        .catch((error) => {
          console.log(error)
        })
    },

You can allow users to login/auth using multiple methods. 您可以允许用户使用多种方法登录/验证。 Then you can merge them together to a single account as described here: 然后,您可以将它们合并到一个帐户,如下所述:

https://firebase.google.com/docs/auth/web/account-linking https://firebase.google.com/docs/auth/web/account-linking

So really it boils down to two options: 所以真的可归结为两种选择:

  1. Allow users to login with multiple methods such as Facebook, Google, Github, basic username/password, etc. 允许用户使用多种方法登录,例如Facebook,Google,Github,基本用户名/密码等。
  2. Or allow only a single login method such as Google only. 或者只允许使用一种登录方法,例如Google。

Whichever options you pick will help you decide which ID to use. 您选择的任何选项都可以帮助您确定要使用的ID。

For your use case it seems like you need to sort out a few steps. 对于您的用例,您似乎需要整理几个步骤。 I'm guessing your application can already connect/use Firebase, but these are essentially it: 我猜你的应用程序已经可以连接/使用Firebase,但这些本质上是:

Step 1 - Connecting 第1步 - 连接

Connect to Firebase using your API key/config as per usual, should look something like the following. 按照惯例使用API​​密钥/配置连接到Firebase,应如下所示。

firebase.initializeApp(config)

See also: https://firebase.google.com/docs/web/setup 另请参阅: https//firebase.google.com/docs/web/setup

You probably already have this somewhere. 你可能已经有了这个地方。 This does not change, but if you would apply the rules as described your users would not be able to use Firebase after just connecting. 这不会改变,但如果您按照描述应用规则,您的用户将无法在连接后使用Firebase。

Step 2 - Authenticating 第2步 - 验证

This is basically telling Firebase who is connected. 这基本上告诉Firebase谁已连接。 This must be done with a token/method Firebase can verify. 必须使用Firebase可以验证的令牌/方法来完成此操作。 Using a Google ID is the most common method. 使用Google ID是最常用的方法。

With an existing Google ID / user login 使用现有的Google ID /用户登录信息

// Initialize a generate OAuth provider with a `google.com` providerId.
var provider = new firebase.auth.OAuthProvider('google.com');
var credential = provider.credential(googleUser.getAuthResponse().id_token);
firebase.auth().signInWithCredential(credential)

See also: https://firebase.google.com/docs/reference/js/firebase.auth.OAuthProvider#credential 另请参阅: https//firebase.google.com/docs/reference/js/firebase.auth.OAuthProvider#credential

Or make Firebase SDK do the login flow 或者让Firebase SDK执行登录流程

var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(function(result) {
  // This gives you a Google Access Token. You can use it to access the Google API.
  var token = result.credential.accessToken;
  // The signed-in user info.
  var user = result.user;
  // ...
})

See also: https://firebase.google.com/docs/auth/web/google-signin 另请参阅: https//firebase.google.com/docs/auth/web/google-signin

This last option is preferred / suggested by the documentation you referenced. 最后一个选项是您引用的文档的首选/建议。

If, as you described, users can already login with Google to your app for other functionalities then you should already have a login flow somewhere. 如果如您所述,用户已经可以使用Google登录您的应用以获取其他功能,那么您应该已经在某处拥有了登录流程。 Depending on your situation it might be advisable to let the Firebase SDK / library take over this process for simplicity in your application. 根据您的具体情况,最好让Firebase SDK /库接管此过程,以简化您的应用程序。

Step 3 - Using the database 第3步 - 使用数据库

Lastly, after authenticating users and applying the rules you suggested you will need to also make sure the paths you write to are within those accessible by the current user. 最后,在对用户进行身份验证并应用您建议的规则之后,您还需要确保您编写的路径位于当前用户可访问的路径之内。 You can put this in a simple function to make it easier. 您可以将其放在一个简单的功能中,以使其更容易。

const getUserRef = (ref) => {
  const user = firebase.auth().currentUser;
  return firebase.database().ref(`/users/${user.uid}/${ref}/`);
}

You should of course not be retrieving the current user every time you want to get a database reference, but I think this clearly illustrates the steps that need to be taken. 当然,每次要获取数据库引用时都不应该检索当前用户,但我认为这清楚地说明了需要采取的步骤。

The auth rules in your question are only stating that the users can read/write their own (presumably) user data. 您问题中的auth规则仅表明用户可以读/写他们自己的(可能是)用户数据。

I assume that you are rather looking for a solution to authorize the user to create meetup data and you should crerate rules similar to this: 我假设您正在寻找一种解决方案来授权用户创建聚合数据,您应该创建类似于此的规则:

These rules allow any user that is logged in to create meetups 这些规则允许登录的任何用户创建聚会

{
  "rules": {
    "meetups": {
      "$meetupId": {
        ".read": "auth.uid != null",
        ".write": "auth.uid != null"
      }
    }
  }
}

Your code-snippet that pushes new meetup data to the database will automatically try and succeed or fail depending on whether the user was logged in or not. 将新的聚会数据推送到数据库的代码片段将自动尝试成功或失败,具体取决于用户是否已登录。 You don't need to specifically tell Firebase in which way the user was logged in. Firebase SDK will take care of the authentication for you. 您无需专门告知Firebase用户登录的方式.Firebase SDK将为您处理身份验证。

But if you do want to provide different mechanisms depending on which login type that the user is authenticated with, you can check it in the rules. 但是,如果您确实希望根据用户通过身份验证的登录类型提供不同的机制,则可以在规则中进行检查。 For example if you want to make sure that the user is not just "anonymously" logged in. 例如,如果您想确保用户不仅仅是“匿名”登录。

See the documentation: https://firebase.google.com/docs/database/security/user-security#section-variable 请参阅文档: https//firebase.google.com/docs/database/security/user-security#section-variable

the documentation has you covered there: Authenticate Using Google Sign-In with JavaScript . 您可以在那里获得文档: 使用JavaScript使用Google登录进行身份验证

You can let your users authenticate with Firebase using their Google Accounts by integrating Google Sign-In into your app. 您可以通过将Google登录集成到您的应用中,让您的用户使用其Google帐户对Firebase进行身份验证。 You can integrate Google Sign-In either by using the Firebase SDK to carry out the sign-in flow, or by carrying out the Google Sign-In flow manually and passing the resulting ID token to Firebase. 您可以使用Firebase SDK执行登录流程,也可以手动执行Google登录流程并将生成的ID令牌传递给Firebase,从而集成Google登录。

Before you begin: 在你开始之前:

  • Add Firebase to your JavaScript project. 将Firebase添加到JavaScript项目中。
  • Enable Google Sign-In in the Firebase console: 在Firebase控制台中启用Google登录:
  • In the Firebase console, open the Auth section. 在Firebase控制台中,打开“身份验证”部分。
  • On the Sign in method tab, enable the Google sign-in method and click Save. 在“登录方法”选项卡上,启用Google登录方法,然后单击“保存”。
  • Handle the sign-in flow with the Firebase SDK If you are building a web app, the easiest way to authenticate your users with Firebase using their Google Accounts is to handle the sign-in flow with the Firebase JavaScript SDK. 使用Firebase SDK处理登录流程如果您要构建Web应用程序,使用Google帐户使用Firebase对用户进行身份验证的最简单方法是使用Firebase JavaScript SDK处理登录流程。 (If you want to authenticate a user in Node.js or other non-browser environment, you must handle the sign-in flow manually.) (如果要在Node.js或其他非浏览器环境中对用户进行身份验证,则必须手动处理登录流。)

To handle the sign-in flow with the Firebase JavaScript SDK, follow these steps: 要使用Firebase JavaScript SDK处理登录流程,请按以下步骤操作:

Create an instance of the Google provider object: 创建Google提供程序对象的实例:

var provider = new firebase.auth.GoogleAuthProvider();

Optional: Specify additional OAuth 2.0 scopes that you want to request from the authentication provider. 可选:指定要从身份验证提供程序请求的其他OAuth 2.0范围。 To add a scope, call addScope() . 要添加范围,请调用addScope()

For example: 例如:

provider.addScope('https://www.googleapis.com/auth/contacts.readonly');

See the authentication provider documentation. 请参阅身份验证提供程序文 Optional: To localize the provider's OAuth flow to the user's preferred language without explicitly passing the relevant custom OAuth parameters, update the language code on the Auth instance before starting the OAuth flow. 可选:要将提供程序的OAuth流本地化为用户首选语言而不显式传递相关的自定义OAuth参数,请在启动OAuth流之前更新Auth实例上的语言代码。

For example: 例如:

firebase.auth().languageCode = 'pt';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

Optional: Specify additional custom OAuth provider parameters that you want to send with the OAuth request. 可选:指定要与OAuth请求一起发送的其他自定义OAuth提供程序参数。 To add a custom parameter, call setCustomParameters on the initialized provider with an object containing the key as specified by the OAuth provider documentation and the corresponding value. 要添加自定义参数,请使用包含OAuth提供程序文档和相应值指定的密钥的对象在初始化的提供程序上调用setCustomParameters。

For example: 例如:

provider.setCustomParameters({
    'login_hint': 'user@example.com'
});

Reserved required OAuth parameters are not allowed and will be ignored. 保留所需的OAuth参数是不允许的,将被忽略。 See the authentication provider reference for more details. 有关详细信息,请参阅身份验证提供程序 Authenticate with Firebase using the Google provider object. 使用Google提供程序对象使用Firebase进行身份验证。 You can prompt your users to sign in with their Google Accounts either by opening a pop-up window or by redirecting to the sign-in page. 您可以通过打开弹出窗口或重定向到登录页面来提示用户使用其Google帐户登录。 The redirect method is preferred on mobile devices. 重定向方法在移动设备上是首选方法。

To sign in with a pop-up window, call signInWithPopup: 要使用弹出窗口登录,请调用signInWithPopup:

firebase.auth().signInWithPopup(provider).then(function(result) {

    // This gives you a Google Access Token. You can use it to access the Google API.
    var token = result.credential.accessToken;
    // The signed-in user info.
    var user = result.user;
    // ...

}).catch(function(error) {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    // The email of the user's account used.
    var email = error.email;
    // The firebase.auth.AuthCredential type that was used.
    var credential = error.credential;
    // ...
});

Also notice that you can retrieve the Google provider's OAuth token which can be used to fetch additional data using the Google APIs. 另请注意,您可以检索Google提供商的OAuth令牌,该令牌可用于使用Google API获取其他数据。 This is also where you can catch and handle errors. 这也是您可以捕获和处理错误的地方。 For a list of error codes have a look at the Auth Reference Docs. 有关错误代码列表,请查看Auth Reference Docs。

To sign in by redirecting to the sign-in page, call signInWithRedirect: 要通过重定向到登录页面来登录,请调用signInWithRedirect:

firebase.auth().signInWithRedirect(provider);

Then, you can also retrieve the Google provider's OAuth token by calling getRedirectResult() when your page loads: 然后,您还可以在页面加载时调用getRedirectResult()来检索Google提供商的OAuth令牌:

firebase.auth().getRedirectResult().then(function(result) {
    if (result.credential) {
        // This gives you a Google Access Token. You can use it to access the Google API.
        var token = result.credential.accessToken;
        // ...
    }

    // The signed-in user info.
    var user = result.user;
}).catch(function(error) {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    // The email of the user's account used.
    var email = error.email;
    // The firebase.auth.AuthCredential type that was used.
    var credential = error.credential;
    // ...
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM