0

I am trying to make a simple website using firebase realtime database. I'm not using PHP to include the session because I don't know how to use PHP with firebase. I do read the documentation but I cannot implement it. How can I create a session to prevent a user able to view the previous page when clicking back button after log out.

The code below is working but still, the user can view the previous page when clicking back button.

firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
            // User is signed in.
            console.log('User is signed in.');
        } else {
            // No user is signed in.
            console.log('No user is signed in.');
            window.location ='login.html'; 
        }
    });
Mary
  • 25
  • 9
  • you can use `JSONWEBTOKEN` to create a token and store the token in your localstorage or you can use `js-cookie` to store the token to your cookie the you can pass a middleware to your pages to check if it is authenticated – Japs Sep 04 '19 at 23:59
  • if (user) {user.getIdToken().then(function(idToken) {}); If I get the token by using this code, what should I do next? – Mary Sep 05 '19 at 00:50

3 Answers3

1

You need to have 3 functions:

FIRST

You need to check the initial load of the page if the browser still have that cookie using the initAuth() function below.

SECOND

You need to make the login/register method to make your user have their token.

THIRD

You need to let the user logout.

It should look something like this:

authenticateUser(content, authData) {
  let authUrl =
    "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" +
    process.env.fbAPIKey;
  if (!authData.isLogin) {
    authUrl =
      "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=" +
      process.env.fbAPIKey;
  }
  return this.$axios
    .$post(authUrl, {
      email: authData.email,
      password: authData.password,
      returnSecureToken: true
    })
    .then(result => {
      content.commit("setToken", result.idToken);
      localStorage.setItem("token", result.idToken);
      localStorage.setItem(
        "tokenExpiration",
        new Date().getTime() + Number.parseInt(result.expiresIn) * 1000
      );
      Cookie.set("jwt", result.idToken);
      Cookie.set(
        "expirationDate",
        new Date().getTime() + Number.parseInt(result.expiresIn) * 1000
      );
      return this.$axios.$post('http://localhost:3000/api/track-data', {data: 'Authenticated!'})
    })
    .catch(e => console.log(e));
}

initAuth(content, req) {
  let token;
  let expirationDate;
  if (req) {
    if (!req.headers.cookie) {
      return;
    }
    const jwtCookie = req.headers.cookie
      .split(";")
      .find(c => c.trim().startsWith("jwt="));
    if (!jwtCookie) {
      return;
    }
    token = jwtCookie.split("=")[1];
    expirationDate = req.headers.cookie
      .split(";")
      .find(c => c.trim().startsWith("expirationDate="))
      .split("=")[1];
  } else if (process.client) {
    token = localStorage.getItem("token");
    expirationDate = localStorage.getItem("tokenExpiration");
  }
  if (new Date().getTime() > +expirationDate || !token) {
    console.log("No token or invalid token");
    content.dispatch("logout");
    return;
  }
  content.commit("setToken", token);
}

logout(content) {
  content.commit("clearToken");
  Cookie.remove("jwt");
  Cookie.remove("expirationDate");
  if (process.client) {
    localStorage.removeItem("token");
    localStorage.removeItem("tokenExpiration");
  }
}

MIDDLEWARE

Then you can call your middleware look like this:

Check for Token first:

context.store.dispatch("initAuth", context.req);

if (!context.store.getters.isAuthenticated) {
    context.redirect("/admin/login");
  }

This is only my point of view and my sample code.

Japs
  • 977
  • 2
  • 10
  • 19
0

It depends on what content on the previous page you're trying to protect. If that is coming from the Firebase Realtime Database, you can typically protect it with security rules. If the content is coming from the HTML/JavaScript on Firebase hosting, there is no way to protect it as all content on Firebase Hosting is public.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • "rules": { "users": {"$uid": {".write": "$uid === auth.uid"} . It is something like this? – Mary Sep 05 '19 at 00:32
  • That's a set of security rules indeed. The exact rules you'll need depend on your exact scenario, so it's impossible for us to answer that in anything but generic terms. – Frank van Puffelen Sep 05 '19 at 01:22
0

The code you included handles when a user logs in/out. You need to put some sort of guards on your pages if you don't want them served to users unless they are logged in. The solution for you depends on how you implement your routing.

Assuming you have no middleware and everything runs in firebase/your app, you simply need to make sure that when the app routes to a new page (that should be protected by login), that your code intercepts and checks if the user is logged in. Your firebase.auth().onAuthStateChanged() handler simply redirects the user to the login screen, and that's all it should be used for. You will need to implement some sort of routing guard on your own, same as having a guard for retrieving data.

jacob13smith
  • 919
  • 5
  • 12
  • For now I can directly access to new page but it will stated no user is signed in. How can I protect this new page? – Mary Sep 05 '19 at 00:37
  • It depends on the framework you are using for the frontend. You need to find where in your app a page is served to the client and insert some sort of middleware to test if the user should be allowed to do the action. – jacob13smith Sep 05 '19 at 00:46