Firebase邮箱验证与登录权限问题:新注册未验证用户可访问成功页
Got it, let's fix this issue step by step. The core problem here is that your current route only checks if a user is signed in, but doesn't validate their email verification status—newly registered users are automatically signed in by Firebase after account creation, so they can bypass the login check and directly access the success page.
Here's how to combine $requireSignIn() with the emailVerified check to lock down the /success route properly:
Step 1: Update the requireAuth Method to Add Email Verification Check
Modify your Authentication service's requireAuth function to not only ensure the user is signed in, but also verify their email status. Since $requireSignIn() returns a Promise that resolves to the authenticated user object, we can chain a .then() to add our custom validation:
requireAuth: function() { return auth.$requireSignIn().then(function(user) { // Block access if email isn't verified if (!user.emailVerified) { throw new Error('EMAIL_NOT_VERIFIED'); } // Return the user object if all checks pass return user; }); }
This update ensures any signed-in user (including newly registered ones) will be blocked from the success page until their email is verified.
Step 2: Add Global Route Error Handling
To make the user experience smooth, add a global handler to catch verification errors and redirect users with a clear message. Add this to your app's run block or main controller:
angular.module('yourAppName').run(function($rootScope, $location) { $rootScope.$on('$routeChangeError', function(event, next, previous, error) { switch(error.message) { case 'EMAIL_NOT_VERIFIED': $rootScope.message = "Please verify your email address first! Check your inbox for the verification link."; $location.path('/login'); break; case 'AUTH_REQUIRED': $rootScope.message = "Please log in to access this page."; $location.path('/login'); break; default: $rootScope.message = error.message || "An unexpected error occurred."; $location.path('/login'); } }); });
Step 3: Keep Login Logic Consistent (Optional)
Your existing login function already checks emailVerified before redirecting, which is great. For full consistency, you could even reuse the requireAuth method here instead of duplicating the check, but your current implementation works perfectly as-is.
Why This Fix Works
- Route-Level Enforcement: The resolve function now blocks access to
/successfor two cases: unauthenticated users, and authenticated users with unverified emails. - Covers All Access Paths: Whether the user tries to navigate via the login page, directly enters the URL, or uses a bookmark, the route guard will catch them.
- Real-Time State Sync: Firebase's
$requireSignIn()returns the latest user state, so once the user verifies their email and refreshes, the check will pass immediately.
Bonus: Improve Registration Feedback (Optional)
Tweak your registration success alert to clarify the verification requirement for new users:
regUser.sendEmailVerification().then(function() { alert("A verification link has been sent to " + regUser.email + ". Please verify your email before accessing your account."); }).catch(function(error) { alert(error); });
内容的提问来源于stack exchange,提问作者Alexandre Asj

