how to reauthenticate user with firebase authentication? - javascript

I'm new to firebase.
In my nuxt js project with multiple pages, firestore rule is set to read or write once request.auth != null.
so if when refresh in a page, auth will be gone and it display error 'permission-denied' in terminal.
i tried Authentication State Persistence LOCAL but it doesn't work.
What is the purpose of using these auth persistence mode ?
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
.then(function() {
return firebase.auth().signInWithEmailAndPassword(email, password);
})

Auth session is automatically persistent on the frontend of your app, however Nuxt.js contains frontend and backend part. If you are storing user data somewhere on the frontend, you probably need to wait until the user data become accessible.
Example of the listener:
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
console.log('User is logged: ', user);
}
});
However this will make user accessible only on the frontend, if you want to preload data on the backend you would need to store id and refresh token in the cookies or use Nuxt Firebase module which should handle service worker for you.
So, in your case it looks like you are trying to read the data before your user data become accessible (this can be caused by trying to fetch data on the backend).

Related

Is the client able to change the user object for onauthchanged firebase realtime database?

I was wondering if the client would be able to change the user object from null to some value (through the console) and gain access to authenticated resources without having to sign in.
I understand that you can use the following code:
auth.onAuthStateChanged(user => {
if (user) {
console.log("user signed in")
console.log(user)
} else {
console.log("user has signed out")
}
});
How does firebase counteract the client attempting to change the user object?
Is there a more secure way of handling this if this is an issue?
How would I implement it?
Thanks.
Changing the user object in the code you shared does not give the user access to additional information in the Firebase Realtime Database.
Inside the security rules for your database, information about the user is exposed through the auth variable. This variable is populated by Firebase from the ID token of the user that makes a request to the database, and it cannot be spoofed by regular users.
So while the user may change the user variable in your client-side code, this does not impact the auth variable in your server-side security rules. This is one of the reasons why it's important to secure data access server-side (like in security rules) and not just client-side.

How do I persist user authentication using the Firebase refresh token?

I am building a React Native app which uses Firebase phone authentication for user login. Authentication works fine but the token expires after an hour. I have read that I need to use the refresh token to refresh the idToken, but nowhere on the Firebase docs does it explain how to do this. It only explains how to revoke refresh tokens, and I can't even find it.
I am using the react-native-firebase package.
My questions are: how to I get the refresh token, how do I use it, and do I really need to call Firebase every hour to update my idToken?
I am currently getting my idToken like this:
const authenticate = async (credential) => {
try {
const { user } = await firebase.auth().signInWithCredential(credential);
const accessToken = await user.getIdToken();
return accessToken;
} catch (error) {
console.log(error);
}
}
I then take the token and store it locally using AsyncStorage and check if the token exists every time the app is launched.
Thanks in advance.
From https://rnfirebase.io/reference/auth/user#getIdToken
It seems that using user.getIdToken() refresh the token if it has expired.
You can always use the forceRefresh option if you want to refresh the token even if it's still valid.

How do I store auth token after user login in vue js?

I am using vue js as a front end and after authenticating user from my appi built with laravel I am receiving a token which is supposed to send with every consequent request for authenticating the api.
But how should I store the token in the browser Securely?
Your question is very broad. So I'm gonna give a general answer.
Use localStorageto store the token.
localStorage.setItem('name','tokenValue'); // to store the token
localStorage.getItem('name'); // to getthe token value
A simple web search will give you all you need to know about localStorage. Hope this helps.
Answer that I found here is very inefficient because localStorage is not assync so after login you would need to refresh entire page which is very bad UX to refresh single page app which I believe is what you develop since you use vue.
What I can suggest istead is localForage which is nothing more than assync localStorage. It is promise based and syntax looks very similiar to localStorage.
Example:
localforage.getItem('something', myCallback);
More info in its docs.
And to send token in every request to backend you should use vue.http.interceptors.
Example:
Vue.http.interceptors.push((request, next) => {
request.headers['Authorization'] = auth.getAuthHeader()
next((response) => {
if(response.status == 401 ) {
auth.logout();
router.go('/login?unauthorized=1');
}
});
});

how to modify laravel middleware to work with firebase authentication

I am working in laravel and firebase as a backend for authentication and data storage. I am using firebase provided js code to signin the user
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
The problem is that I want to protect my routes from non-authenticated users. How would I check this in my middleware that user is logged in or not because js stores current user's uid in localStorage. Do I have to use a separate database for this purpose? Please help me to go in right direction.
You have to call:
auth.currentUser.getIdToken().then(function(token) {
// The Firebase id token is returned here.
// You will have to send that along your requests to your server.
// Keep in mind this is a short lived token
// You have to call getToken each time you need it in case
// it is auto refreshed underneath.
});
Currently, Firebase provides node.js and java backend libraries to verify the token (to check the user is logged in).
https://firebase.google.com/docs/auth/server
A php library is in the works. When it is ready, it should provide similar functionality for minting custom tokens and verifying Firebase id tokens.
You can simply use this https://github.com/vinkas0/firebase-auth-laravel laravel package to authenticate via firebase

What is it the best solution to hide a single page application private pages with Firebase?

I'm going to explain the problem better with an example, in this Firebase official example https://office-mover-demo.firebaseapp.com/ I can show the hidden page without login with a simple command in the console:
app.classList.remove('is-hidden');
Yes, of course, the data in firebase can be accessed only if a user successful logged in. So my question is: Can i do something to show the structure of the html private part only after a successful login of the user? (Only with static content and firebase auth)
From the Firebase documentation on monitoring authentication state:
// Create a callback which logs the current auth state
function authDataCallback(authData) {
if (authData) {
console.log("User " + authData.uid + " is logged in with " + authData.provider);
} else {
console.log("User is logged out");
}
}
// Register the callback to be fired every time auth state changes
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.onAuth(authDataCallback);
Where the snippet calls console.log, you can just as easily show/hide the HTML.
My solution to this problem - as I understand it - is to set a cookie upon user login containing the user's id or, with an additional call to Firebase, a secret visible only to the logged in client. My server can then read the cookie and determine whether the user is authorized to view the content and only then download it. Thus, I am using Firebase for authentication, but my own server for authorization.
It works, and I can also log the user in to my server using this approach just as if I had received an Oauth token.
However, lacking experience with cookies, I would like to know how secure this is!

Categories

Resources