如何防止同一用户同时登录 Firebase? [英] How to prevent simultaneous logins of the same user with Firebase?

查看:32
本文介绍了如何防止同一用户同时登录 Firebase?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望新会话能够从本质上注销"之前的任何会话.例如,当您在一台计算机上进行经过身份验证的会话时,在另一台计算机上启动一个新会话并在我们的应用上使用 firebase 进行身份验证将注销第一台计算机上的另一个会话.

I'd like for the new session to essentially "log out" of any previous session. For example, when you are in an authenticated session in one computer, starting a new session on another computer and authenticating with firebase on our app will log out the other session on the first computer.

我找不到任何允许我远程"注销会话的方法.我知道我可以在会话中 unauth() 和 goOffline() .但是如何从同一用户的不同身份验证会话中执行此操作?

I haven't been able to find any method that allows me to log out of a session "remotely". I know that I can unauth() and goOffline() from within a session. But how do I do it from a different authenticated session of the same user?

感谢您的帮助!

背景信息:

  1. 我使用简单的电子邮件/密码登录进行 firebase 身份验证
  2. 我还没有设置安全规则,虽然正在开发中
  3. 我在 Firebase 中使用 Javascript

推荐答案

总体思路是,您希望在 Firebase 中创建一些元数据,以告诉您用户从多少个位置登录.然后您可以使用这些信息限制他们的访问.

The general idea is that you want to create some meta data in Firebase which tells you how many locations a user is logged in from. Then you can restrict their access using this information.

为此,您需要生成自己的令牌(以便您的安全规则可以使用该信息).

To do this, you'll need to generate your own tokens (so that the information is available to your security rules).

1) 生成令牌

使用自定义登录生成您自己的令牌.每个令牌都应包含客户端的唯一 ID(IP 地址?UUID?)

Use custom login to generate your own tokens. Each token should contain a unique ID for the client (IP Address? UUID?)

var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator(YOUR_FIREBASE_SECRET);
var token = tokenGenerator.createToken({ id: USER_ID, location_id: IP_ADDRESS });

2) 使用状态来存储用户的 location_id

查看管理状态入门以了解详情:

var fb = new Firebase(URL);

// after getting auth token back from your server
var parts = deconstructJWT(token);
var ref = fb.child('logged_in_users/'+token.id);

// store the user's location id
ref.set(token.location_id);

// remove location id when user logs out
ref.onDisconnect().remove();

// Helper function to extract claims from a JWT. Does *not* verify the
// validity of the token.
// credits: https://github.com/firebase/angularFire/blob/e8c1d33f34ee5461c0bcd01fc316bcf0649deec6/angularfire.js
function deconstructJWT(token) {
  var segments = token.split(".");
  if (!segments instanceof Array || segments.length !== 3) {
    throw new Error("Invalid JWT");
  }
  var claims = segments[1];
  if (window.atob) {
    return JSON.parse(decodeURIComponent(escape(window.atob(claims))));
  }
  return token;
}

3) 添加安全规则

在安全规则中,强制只有当前唯一位置可以读取数据

In security rules, enforce that only the current unique location may read data

{
  "some_restricted_path": {
     ".read": "root.child('logged_in_users/'+auth.id).val() === auth.location_id"
  }
}

4) 控制对 login_in_users 的写访问

您需要设置一些系统来控制对logged_in_users 的写访问.显然,用户应该只能写入他们自己的记录.如果您希望第一次登录尝试始终获胜,则使用 ".write": "!data.exists()"

You'll want to set up some system of controlling write access to logged_in_users. Obviously a user should only be able to write to their own record. If you want the first login attempt to always win, then prevent write if a value exists (until they log out) by using ".write": "!data.exists()"

但是,您可以通过让最后一次登录获胜来大大简化,在这种情况下,它会覆盖旧的位置值,并且之前的登录将失效且无法读取.

However, you can greatly simplify by allowing the last login to win, in which case it overwrites the old location value and the previous logins will be invalidated and fail to read.

5) 这不是控制并发数的解决方案

您不能使用它来防止多个并发到您的 Firebase.有关完成此操作的更多数据,请参阅 goOffline() 和 goOnline()(或获得付费计划,这样您就没有连接的硬性上限).

You can't use this to prevent multiple concurrents to your Firebase. See goOffline() and goOnline() for more data on accomplishing this (or get a paid plan so you have no hard cap on connections).

这篇关于如何防止同一用户同时登录 Firebase?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆