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

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

问题描述

我希望新的会议基本上注销任何以前的会议。例如,当您在一台计算机中进行身份验证的会话时,在另一台计算机上启动一个新会话并使用我们的应用程序上的Firebase进行身份验证将会在第一台计算机上注销其他会话。



我没有找到任何方法让我远程退出会话。我知道我可以在会话中使用unauth()和goOffline()。但是,如何从同一用户的不同身份验证会话中执行此操作?



感谢您的帮助!

背景信息


  1. 我使用简单的电子邮件/密码登录进行Firebase身份验证

  2. 我还没有设置安全规则,尽管这是安全规则。

  3. 我在Firebase中使用Javascript


解决方案

一般的想法是,您想在Firebase中创建一些元数据,告诉您用户登录的位置。然后,您可以使用这些信息来限制他们的访问。



为此,您需要生成自己的令牌(以便您的安全规则可以使用这些信息) 。
$ b $ p <1>生成一个令牌



使用自定义登录来生成自己的令牌。每个标记应该包含一个唯一的客户端ID(IP地址?UUID?)

$ p $ var $ FirebaseTokenGenerator = require(firebase-token -发电机);
var tokenGenerator =新的FirebaseTokenGenerator(YOUR_FIREBASE_SECRET);
var token = tokenGenerator.createToken({id:USER_ID,location_id:IP_ADDRESS});

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



查看管理状态入门详情:

  var fb =新的Firebase(网址); 

//从服务器获取授权令牌之后
var parts = deconstructJWT(token);
var ref = fb.child('logged_in_users /'+ token.id);

//存储用户的位置id
ref.set(token.location_id);

//当用户注销时删除位置ID
ref.onDisconnect()。remove();

//辅助函数从JWT中提取声明。 *不*验证令牌的
//有效性。
// 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))));
}
返回令牌;




$ b

3)添加安全规则



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

  { 
some_restricted_pa​​th:{
.read:root.child('logged_in_users /'+ auth.id).val()=== auth.location_id
}




$ b $ p <4>控制对logged_in_users的写访问



您需要设置一些控制对logged_in_users的写入权限的系统。显然用户只能写自己的记录。如果您希望第一次登录尝试总是胜出,那么通过使用write:!data.exists()来防止写入(如果存在值)然而,你可以通过允许上次登录获胜而大大简化,在这种情况下,它会覆盖旧的位置值,并且以前的登录将失效并失败阅读。



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

<您无法使用此功能来防止Firebase发生多重共谋。请参阅goOffline()和goOnline()以获取更多有关完成此操作的数据(或者获得付费计划,这样您就没有硬连接的限制)。

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.

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?

Thanks for the help!

Background Info:

  1. I am using simple email/password login for firebase authentication
  2. I don't have security rules setup yet, although this is in the works
  3. I'm using Javascript with 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) Generate a token

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) Use presence to store the user's location_id

Check out the managing presence primer for details:

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) Add security rules

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) Control write access to logged_in_users

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) This is not a solution to control the number of concurrents

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天全站免登陆