Custom Firebase token generation

175 views
Skip to first unread message

dr

unread,
Mar 25, 2015, 10:57:13 AM3/25/15
to fireba...@googlegroups.com
My end goal is to add ROLES and ORGS and whatever other data to the AUTH token for use in the firebase security rules. Below is some pseudo code, thinking about just wrapping the token generation in a simple api. Any suggestions or other ways of doing this would be greatly appreciated.



require('dotenv').load();

var Promise = require('bluebird');
var Firebase = require('firebase');
var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator(process.env.FIREBASE_SECRET);
var express = require('express');

var fb = new Firebase(process.env.FIREBASE_URL);
var fbAuth = Promise.promisify(fb.auth, fb);

var app = express();

app.post('/auth', function (req, res) {
fbAuth(req.token)
.then(function(result) {
// add ROLES to valid token, by firebase query
// add other data valid token, by firebase query
var token = tokenGenerator.createToken({uid: result.auth.uid, some: "arbitrary", data: "here"});
res.json(token);
})
.catch(function(err) {
res.error('bad auth', err);
});
});


app.listen(3000);

Kato Richardson

unread,
Mar 26, 2015, 2:32:59 AM3/26/15
to fireba...@googlegroups.com
Hello! We're entering into a pretty broad topic here and the amount of detail you've provided won't start to narrow the scope. It's hard, for example, to take a guess at why you've chosen to use tokens and whether that's a good choice or not.

Generally speaking, I'd definitely start with security rules, rather than trying to enforce security using a server-side worker process or via some content baked into the auth tokens. These two Stack Overflow posts, plus the security doc on user based security should be a great primer to get started on defining roles in your data and referencing them from security rules:

Cheers,
Kato


--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/0eedc2d0-8bbc-4e5a-adbb-8019da634b49%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

dr

unread,
Mar 26, 2015, 3:00:07 PM3/26/15
to fireba...@googlegroups.com
Yeah, the general idea was to make the security rules easier to read and easier to create by having more data in the auth token.

dr

unread,
Mar 27, 2015, 2:50:21 PM3/27/15
to fireba...@googlegroups.com
I have been working on these security rules to accomplish the following.

> Users sign up
> Organization's invite user to organization (organization_users)
> User accepts invite from organization (user_organizations)
> Admin's (from any user accepted invites) organizations can read the user_data

The security rules link above really assumes a user can only be part of a single organization. I would like any Admin of an organization that a user belongs to, to be able to read the user data.

Any help or guidance you could provide would be greatly appreciated. Maybe i am going about this all wrong.

Jacob Wenger

unread,
Apr 5, 2015, 2:22:11 PM4/5/15
to fireba...@googlegroups.com
Hey there,

This is going to be difficult unless (1) you have the organization ID ($orgId) in your path or (2) a user can only be in one organization. The security rules don't have a forEach() method to iterate over children dynamically. So you cannot, say, check if the logged in user is an admin of any of the orgs listed for a user. However, if you are able to organize you data so that either (1) or (2) holds, you rules can look like this:

(1)  You have the organization ID ($orgId) in your path

"user_data": {
  "$uid": {
    ".read": "auth.uid === uid || root.child('organization_user_roles').child($orgId).child(auth.uid).exists()"
  }
}

(2)  A user can only be in one organization

"user_data": {
  "$uid": {
    ".read": "auth.uid === uid || root.child('organization_user_roles').child(newData.child('orgId').val()).child(auth.uid).exists()"
  }
}

Hope that helps,
Jacob

Reply all
Reply to author
Forward
0 new messages