0

I have a function that checks wether the password and user match before authenticating using a custom token.

function getUser(user, password) {
    var usersRef = new Firebase("mydatabase/users");
    var userRef = usersRef.child(user);
    userRef.once("value", 
        function getHandler(snapshot) {
            if (snapshot.val().password == password) {
                var token = createToken(user);
                ref.authWithCustomToken(token, authHandler);
            } else {
                alert("Gebruikersnaam en code komen niet overeen");
            }
        },
        function errorHandler(errorObject) {
            alert("Ophalen van gebruikersgegevens is mislukt: " + errorObject.code);
        }
    );
}

To create e token I instantiate the firebase class FirebaseTokenGenerator with the secret key. Like

function createToken(user) {
    var tokenGenerator = new FirebaseTokenGenerator("<secret key...>");
    var updatedObj = {
        "uid": "custom:"+user,
        "level": "docent"
    }
    return tokenGenerator.createToken(updatedObj);

However in that way the secret key would be visible for anyone looking into the .js source code. I'm pretty sure that is not how it should be done but what is the right way to do this then, the Firebase-way?

EDIT:

I tried to figure out the javascript way for this but got stuck there so switched back to php. Used the firebase-token-generator code from github (here), installed it including dependencies in my project with composer and that all seems to work fine (token is generated).

<?php
  include_once "FirebaseToken.php";

  $uid = $_POST['uid'];
  $level = $_POST['level'];

  $tokenGen = new Services_FirebaseTokenGenerator("<secret key>");
  $token = $tokenGen->createToken(array("uid" => "custom:BAAJ"), array("admin" => False));
  echo $token;
?>

Reading this SO post I found that following would be the way to embed it in my javascript code:

function createToken(user) {
    $.post('php/createtoken.php', {uid: user, level: 'docent'}, function(data){
            //successful ajax request
            return data;
        }).error(function(error){
            alert("Create token mislukt: "+error);
        });
};

But for som reason the token is not generated then. When called from getUser at first both the success and error part of the javascript createToken function are not executed at all (resulting in an undefined value for variable token. Then createToken is called a second time (??) and then the success part is executed however the data now does not contain the token but the complete php script...?

What is the problem and how to solve?

Community
  • 1
  • 1
user1837293
  • 1,466
  • 3
  • 16
  • 30
  • any type of javascript verification is insecure, because as you said, anyone can see or edit the javascript client-side. The proper way to do it would be with php, which is server side and secure. I believe you are doing everything else correctly though. – Xander Luciano Apr 28 '15 at 07:05
  • 1
    @ViperCode PHP is server side, yes. Secure? Eh. It's as secure as you write it to be, and it doesn't have to necessarily be PHP. – Madara's Ghost Apr 28 '15 at 07:10

2 Answers2

3

You should avoid to do anything 'secret' in the client browser. There, the secret will be visible, password will be hackable via XSS and sniffable and you could connect to any user with some XSS.

You should rather move this part onto the server side to be more secure, it could be NodeJS, PHP or anything else. (HTTPS connections, obviously)

Alexis Paques
  • 1,885
  • 15
  • 29
  • Can you tell what the code would look like using nodeJS (sticking to JavaScript) on a firebase-hosted app? – user1837293 Apr 28 '15 at 09:40
  • I suppose the code itself wouldn't be much different but I don't know how to make sure the code is executed server-side (using NodeJS). How do I make that happen? – user1837293 Apr 28 '15 at 10:08
  • 1
    On NodeJS you will have an express server. Then use a [middleware with app.use()](http://expressjs.com/guide/using-middleware.html) to deny unauthorized clients. [Here is a complete example](http://code.tutsplus.com/tutorials/authenticating-nodejs-applications-with-passport--cms-21619) – Alexis Paques Apr 28 '15 at 11:24
  • I tried that but got stuck and switched back to php. Pls see question edit for issue i run into there? I tried on local server and remote (firebase) server, both same issue. – user1837293 Apr 29 '15 at 21:05
0

You have to do this in your server side application and send the generated token to your client app. The token should be sent over HTTPS as well. Default token expiry is 24 hours. This can be changed.

Jerome Anthony
  • 7,823
  • 2
  • 40
  • 31