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?

2
  • 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. Commented Apr 28, 2015 at 7: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. Commented Apr 28, 2015 at 7:10

2 Answers 2

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)

Sign up to request clarification or add additional context in comments.

4 Comments

Can you tell what the code would look like using nodeJS (sticking to JavaScript) on a firebase-hosted app?
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?
On NodeJS you will have an express server. Then use a middleware with app.use() to deny unauthorized clients. Here is a complete example
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.
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.