For now I'm doing like this:
firebase.auth().onAuthStateChanged((user) => {
if (!user.emailVerified) {
//Something
}
});
But, the problem is I have added this block of code in multiple pages and whenever the authentication changed (user logged in or logged out) It calls all those functions and that effects other code!
So, is there any way by which we get if users email is verified or not - without using 'onAuthStateChanged()'
Anywhere in your page you can do:
firebase.auth().currentUser.emailVerified
To determine the current state. You only need onAuthStateChanged() to monitor when the state changes.
listener
onIdTokenChanged
to reload
auth.currentUser.reload()
auth.currentUser.getIdToken(true)
Related
This question already has answers here:
Checking auth token valid before route enter in Vue router
(5 answers)
Closed 2 years ago.
I want to test if the user has login or not, if not he will return to login page.
I want the script that check if the user has login to be executed before html (or template) load.
I have tried
beforeCreate()
and other things, but html still load before the script run.
this is my code
if(sessionStorage.getItem("email") == undefined) location.href = "/";
edit
I made this vue project using CLI so I dont have the normal index.html with head and body where i can simply add script anywhere outside vue.
It isn't considered "best practice" to implement security code using JavaScript. If a user turns off JavaScript in their browser, they have effectively bypassed your security.
Instead, use server-side code to detect if the current user is logged in, and if not, send an HTML redirect to the login page instead of the normal HTML content.
Pseudo code (as you haven't specified any server-side language):
if(userLogin <> true)
Return HtmlRedirect("YourLoginPage")
...
Return CuurrentPage
This method prevents any HTML being sent to the user if they are not authorised to see it.
try checking if your condition matches before initiating vue instance and initiate it after satisfying the condition like this:
if(sessionStorage.getItem("email") == undefined) {
location.href = "/";
} else {
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
}
I agree with #Dragonlaird said mentioning that it is not a best practice to handle it from the client-side. However, I think you have to try beforeMount or beforeUpdate instead of beforeCreate since you need to do the stuff before HTML (or template) load. According to the Vue.js documentation,
beforeMount:
It is called right before the mounting begins: the render function is about to be called for the first time.
But this hook(beforeMount) is not called during server-side rendering.
beforeUpdate:
It is called when data changes before the DOM is patched. This is a good place to access the existing DOM before an update, e.g. to remove manually added event listeners.
This hook is also not called during server-side rendering, because only the initial render is performed server-side.
For further information please refer Vue.js documentation.
https://v2.vuejs.org/v2/api/#Options-Lifecycle-Hooks
I am using Angular 8
Task sounds like this: user opens application in two tabs. User is signed in. And if user signs out in the first tab, then second tab should redirect user to /login.
I am using localstorage to store user's data and storage dom event which triggers when localstorage changes.
Here is my code:
private _redirectIfUserLoggedOut(): void {
window.addEventListener('storage', this._onStorageListener);
}
private _onStorageListener = () => {
const currentUser = localStorage.getItem('__session_token');
if (!currentUser) {
this._router.navigate(['/login']) // this call doesn't work
}
}
The problem is: this._router.navigate doesn't work. Just nothing happens. But when I change this._router.navigate to window.location.href = '/login' redirection works.
this and this._router are not undefined
No errors or warnings in a console.
What is wrong with above code?
The problem is that when the event is triggered, the callback is executed from a different context i.e. from the window. So this in that case would refer to window, and there you don't have the router injected.
You could try to bind your service this to the event listener using:
window.addEventListener('storage', this._onStorageListener.bind(this));
So this is my problem.
I can successfully login from my angularJS app using the auth factory i made that communicates to my pp rest API.
lets say Auth.login(user) -> (POST) myapi.com/user/login: the response is the user object that Auth saves locally. Thus Auth.getCurrentUser() returns local user object.
my rest API, i also have a myapi.com/user/get_loggedin_user which returns the current logged in user (using the php session). So if Auth.getCurrentUser should actually check if local user exists, if not do an ajax to myapi.com/user/get_loggedin_user and check if logged in before responding with null. One problem here is, ajax is annoying like this, you would then need to put in a success callback function and have all your code execute inside the success callback.
Now lets say im on the Angular App (website), mydomain.com/user/dashboard (already logged in), and then i refresh my browser. Now, when the page reloads, angular does not know my current user, so before it redirects me to mydomain/login, i want it to check if the user is logged in. i can obviously do a 1 time call within the controller, but is there a more easy way where i can register within a controller with some access restrictions (Eg: logged_in == true), and when you visit any page with logged in requirement, it checks local user (gets the user if does not exist), and redirects to login page if null, or display the page once it matches the requirements?
Different common page requirements: null, logged_in, admin, function: haveAccess(user, object).
NOTE: im using stateProvider
If I understood your question correctly, you are asking about how to check whether the user is logged in before the controller is invoked, and to avoid the check for a logged-in status in each controller that needs it.
If so, you should look into the resolve parameter - this exists both in $routerProvider and $stateProvide.
Essentially you could "resolve" your loggedInUser variable (by doing whatever you need to do via your MyAuth service.
Here's an example of what I mean with $routeProvider:
$routeProvider
.when("/someSecuredContent", {
templateUrl: 'someSecuredContent.html',
controller: 'SecuredController',
resolve: {
loggedInUser: function(MyAuth){
return MyAuth.loggedIn(); // MyAuth.loggedIn() should return a $q promise
}
}
});
Then in the controller, loggedInUser will be injected.
Here's a site with more examples.
Correct me if im wrong:
Do this within the Main Controller (make sure you inject the dependancies like rootScope, state, and your own Authfactory)
$rootScope.$on('$stateChangeStart', function (event, next, toParams) {
if (needToBeLoggedIn()) { //use the next object to read any data, and you can set on the state some flag
event.preventDefault()
MyAuth.loggedIn(function success(){ $state.go(next,toParams); }, function err (){/*send somewhere else*/});
}
})
Put logged_in = true to cookieStore in your login method after authentication as below.
$cookieStore.put('logged_in',true);
$rootScope.logged_in = true;
and in your Controller, do
$rootScope.logged_in = $cookieStore.get('logged_in');
Now you can use this logged_in variable anywhere in the UI to check if the user is logged in.
Make sure to use 'ngCookies' module in your app. and pass the $cookieStore dependency to your controller. You can even keep the user object itself similar to logged_in variable in cookies and retrieve it from cookies.
Make sure to do logged_in = false and clear other variables in cookies and set it to blank in your logout method.
In my app I use accounts-github. Works perfect, but I have one problem.
In one of my templates I do
Template.bar.rendered = function () {
if (Meteor.user()) {
// setup stuff
}
}
The problem is that if the user initially is not logged in this code is not executed (thats ok). But when the user authenticates this code is not executed again. So the question is how can I listen for this change inside a template (doesn't have to be in inside the rendered function!)?
You could use Deps.autorun. (http://docs.meteor.com/#deps_autorun)
Usually Deps.autorun would run for your whole Meteor app. If you want to make it so that it only runs per template you would need to create and stop it in the rendered and destroyed template callbacks
e.g
var loginRun;
Template.bar.rendered = function() {
loginRun = Deps.autorun(function() {
if(Meteor.user()) {
//Stuff to run when logged in
}
});
}
Template.bar.destroyed = function() {
loginRun.stop();
}
If you don't need it to run per template (need it to run just once for you app on any template, then you can use the Deps.autorun on its own, anywhere in your client side code.
Meteor.user() is reactive, it would ensure that the Deps.autorun callback runs again when it changes, so you could theoretically use it to do things when the user logs in or out.
Other alternatives is there is a package on atmosphere that provides login and logout hooks, though they basically would use the Deps.autorun like above to work anyway. See https://github.com/BenjaminRH/meteor-event-hooks
My solution for similar problem was to
Attach an event to template where the login happens
Re-render template if login is succesful so the Template.bar.rendered is called
E.g.
Template.bar.events({
'click .loginButton' : function() {
if( Meteor.call.Login( username, pw ) )
{
$('#bar').html( Meteor.render( Template.bar ));
//jQuery is optional
}
});
I've been poking around in the Accounts packages, using a modified version of the ever-fabulous EventedMind Customizing Login screencast.
I modified it to use facebook instead of github, and I noticed something when trying to update user.profile information. Specifically, I'm looking for the right way/place to handle changes to user.profile.
Let's say, for example, that I authenticate as a FB user for the first time. When I do this, the CreateUser event will fire.
Using Accounts.onCreateUser(...), I can populate additional information from the FB graph into the profile, like so:
Accounts.onCreateUser(function(options,user){
var accessToken = user.services.facebook.accessToken,
result;
result = Meteor.http.get("https://graph.facebook.com/"+user.services.facebook.username, {
params: {
access_token:accessToken,
fields: ['picture', 'name','first_name','last_name','username','link','location','bio','relationship_status','email','timezone','locale']
}
});
if (result.error){
throw result.error;
}
user.profile = result.data; //lazily adding everything
return user;
});
This works just fine when the user is created. It's nice and clean.
But now let's say that some of the information changes. For example, let's say that the profile picture changes. If I log out and then back in to the meteor application, Accounts.onCreateUser(...) doesn't fire, because the user already exists. It's not being created again, it's being modified.
I need to update the user.profile on subsequent logins, or at least check for changes and then modify as needed. I'd ideally like to do this in similar fashion to .onCreateUser. Maybe with a .onModifyUser or something...
I can figure a couple of ways to do this using some checking and/or client-side code, but I'm wondering if there is an already-existing server hook that would be cleaner.
Any recommendations on the cleanest way to handle this situation?
Thanks in advance.
If you're manually calling the login functions you can pass a callback as the last parameter which will get called on the client after the login completes. See: http://docs.meteor.com/#meteor_loginwithpassword.
Meteor.loginWithFacebook({}, function (err) { /* make a Meteor method call here */ });
There are no documented server side callbacks at the moment.