- Notifications
You must be signed in to change notification settings - Fork2.2k
Feature Request: Support server-side authentication in AngularFireAuth#1500
-
I am currently developing an angular universal app powered by firebase and angularfire2 (for authentication and database/firestore). I have the following scenario: There is many routes and many components inside the project! For the following scenario i will consider only 3 routes/components 1- Home Component (authentication is not required) To make things working with an authentication process within an angular app, we use the "canActivate guard"! Workflow in the canActivate guard:
@Injectable()exportclassAuthGuardimplementsCanActivate{constructor(privateauth:AuthService,privaterouter:Router){}canActivate(next:ActivatedRouteSnapshot,state:RouterStateSnapshot):Observable<boolean>|boolean{returnthis.auth.user$.take(1).map(user=>!!user).do(loggedIn=>{if(!loggedIn){console.log('access denied');this.router.navigate(['/login']);}else{this.router.navigate(['/user']);}});}} this.auth.user$ is equal to@Injectable()exportclassAuthService{publicuser:IUser;publicuser$:Observable<IUser>;private_authDialogRef:MatDialogRef<any>;constructor(privateafAuth:AngularFireAuth,privateafs:AngularFirestore,private_dialog:MatDialog,privaterouter:Router){// Get auth data, then get firestore user$ document || nullthis.user$=this.afAuth.authState However, client side rendering is working like expected but no the server side! Angular Universal - SSR - canActivate Result:when the guard is triggered on the server side, the login page will be rendered and then after few seconds the client side render the whole thing again and will be redirected to the user page. How can we solve the above described scenario? RequestPlease support firebase authentication on the server side too Note (ideas): supporting firebase authentication for angular universal app through JWT - headers / cookies ???? |
BetaWas this translation helpful?Give feedback.
All reactions
👍 11😕 1❤️ 1
Replies: 24 comments 8 replies
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
I have the same problem, looking for solution of this scenario :) if we can fix this, it will be completed eco system for angular with minimum cost. what about angular state transfer ? |
BetaWas this translation helpful?Give feedback.
All reactions
👍 2
-
While not an official solution, I have used dependency injection + firebase admin to work on server side See: The idea is, you only need to use the |
BetaWas this translation helpful?Give feedback.
All reactions
👍 3
-
|
BetaWas this translation helpful?Give feedback.
All reactions
-
How do you intend to transmit a Authorization header from the first server request? The web browser WILL send stored cookies, but has no ability to know you intend to send an Authorization header. Cookies are also more secure in general. I highly recommend you use Cookies in your universal application. |
BetaWas this translation helpful?Give feedback.
All reactions
👍 1
-
@davideast do you have any suggestion sir? |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
Like@hiepxanh mentioned above... This would complete the SSR + Angular + Firebase visionquest. The only thing I've come up w/ so far (and this just a hack to get rid of auth'd refresh flicker) is to canActivate():Observable<boolean>|boolean{if(typeofwindow!=='undefined'){returnthis.afAuth.user.pipe(take(1),map(state=>!!state),tap(loggedIn=>{if(!loggedIn){this.system.log('You must be logged in.');this.router.navigate(['/login']);}}));}returntrue;} This just flips the problem around, to where when you hit a route-guarded page without auth, it will flicker the unauthorized page on the initial render, and then kick you back to the login page once it's got the firebase user response in the client. Again, FYI - This is a total hack. |
BetaWas this translation helpful?Give feedback.
All reactions
👍 2
-
this saved my day 7 years later |
BetaWas this translation helpful?Give feedback.
All reactions
-
Just checking back in here to see if anyone has made any progress on this? |
BetaWas this translation helpful?Give feedback.
All reactions
-
I've looking into this BTW. For server side auth right now I recommend a cloud function that issues a cookie via the admin SDK. I'll come up with some recommendations / put some work into the Auth module soon to make it work better out of the box. |
BetaWas this translation helpful?Give feedback.
All reactions
👍 2
-
I will also be writing a module for this soon - will post back here once its ready :) |
BetaWas this translation helpful?Give feedback.
All reactions
👍 1
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
just saw these... 🤔 |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
Hey@jrodl3r , did you try this new things out? Is it working with ssr? Thanks |
BetaWas this translation helpful?Give feedback.
All reactions
-
hi@simkepal, currently setting up a system w/ latest angular-universal (8) on a gcloud app-engine instance - so far, SSR is working great with node 10. will update after setting up auth and testing out new guard stuff 👍 |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
@jamesdaniels so, this works on local angular + SSR from gCloud instance: constisAdmin=()=>pipe(customClaims,map(claims=>{returnclaims.admin===true ?claims.admin :['/'];}));constroutes:Routes=[…,{path:'admin',component:AdminComponent,canActivate:[AngularFireAuthGuard],data:{authGuardPipe:isAdmin}},]; however, the pre-built ones like constredirectUnauthorizedToLogin=redirectUnauthorizedTo(['login']);constroutes:Routes=[…,{path:'profile',component:ProfileComponent, ...canActivate(redirectUnauthorizedToLogin)},]; this has been crashing my canary tab regularly =\ constredirectUnauthorized=map((user:IUser)=>user ?['profile'] :['login']); great news that we can verify the admin claim, just need to fix verifying the logged-in user. Update: this works in both local Angular + gCloud SSR instance 😄 constisLoggedIn=()=>pipe(map(user=>!!user ?true :['/']));constisLoggedOut=()=>pipe(map(user=>!!user ?['profile'] :true));constisAdmin=()=>pipe(customClaims,map(claims=>claims.admin===true ?claims.admin :['/']));constroutes:Routes=[{path:'',component:HomeComponent},{path:'login',component:LoginComponent,canActivate:[AngularFireAuthGuard],data:{authGuardPipe:isLoggedOut}},{path:'admin',component:AdminComponent,canActivate:[AngularFireAuthGuard],data:{authGuardPipe:isAdmin}},{path:'profile',component:ProfileComponent,canActivate:[AngularFireAuthGuard],data:{authGuardPipe:isLoggedIn}},{path:'**',component:ErrorComponent}]; also works on lazy-loaded module routes 👍 constroutes:Routes=[…,{path:'admin',loadChildren :()=>import('./components/_admin/admin.module').then(m=>m.AdminModule),canActivate:[AngularFireAuthGuard],data:{authGuardPipe:isAdmin}}} |
BetaWas this translation helpful?Give feedback.
All reactions
👍 3
-
I am so confused, could someone wrap it up? does |
BetaWas this translation helpful?Give feedback.
All reactions
-
I found a good stopgap solution, until there's a good way to check auth server-side with Angular Universal. Assuming your guard redirects to login, on your login page, show a loading spinner until the frontend can resolve auth. Then what happens is, if you try to load an auth-protected route, the user sees a loading spinner momentarily until auth resolves. To make this work, you have to set up your login template to ensure it prerenders showing the spinner. This is ok, since you should not need SEO on your login route. I did it like this: login.component.html: <ng-container*ngIf="authResolved; else showLoading"><!-- login form here --></ng-container><ng-template#showLoading><!-- this is a component that holds a spinner --><app-loading-overlay[loading]="true"behavior="full"></app-loading-overlay></ng-template> login.component.ts: authResolved=false;constructor(privateafAuth:AngularFireAuth, @Inject(PLATFORM_ID)privateplatformId,){}ngOnInit(){if(isPlatformBrowser(this.platformId)){// show spinner till frontend can determine if user is logged inthis.afAuth.authState.pipe(map(user=>!!user),take(1)// this way the observable completes and we don't need to unsubscribe).subscribe(()=>{this.authResolved=true;});}} |
BetaWas this translation helpful?Give feedback.
All reactions
👍 1
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
Thanks that helped me a lot |
BetaWas this translation helpful?Give feedback.
All reactions
-
Are there any plans to make the AngularFireAuth Service work on server for SSR? |
BetaWas this translation helpful?Give feedback.
All reactions
-
I'm also getting stuck with the same issue in Angular SSR. Is there any solution for it? |
BetaWas this translation helpful?Give feedback.
All reactions
-
I'm hoping to add official support for it in a future release but I'd suggest cookie auth for SSR. |
BetaWas this translation helpful?Give feedback.
All reactions
❤️ 1
-
Is there any progress on SSR with authentification? An official solution would be much appreciated. I'm using AngularFire with email + password authentification and would like to add SSR if there is an easy solution. I read that we can use SSR without authentification out of the box and can even "activate" a cloud function. But I'm unsure what the cloud function does. SSR is actually new for me so I would very much appreciate any advise on how to implement SSR with authentificiation. Probably this is already working out of the box and I just missed something, did I? Love AngularFire btw. Great work. |
BetaWas this translation helpful?Give feedback.
All reactions
👀 1
-
Hi@jamesdaniels, are there still any plans for this feature request? Thank you in advance. |
BetaWas this translation helpful?Give feedback.
All reactions
-
We're actively working on a proper server-side auth story for Firebase ATM. No ETA to share but it's a high priority. |
BetaWas this translation helpful?Give feedback.
All reactions
-
Cool, thank you for the update. Do you have an example repo with a workaround that can be used in meantime? That would help a LOT. Thank you in advance. |
BetaWas this translation helpful?Give feedback.
All reactions
-
There's not currently a work-around that I can give and feel good about; even the best solutions would be prone to race conditions and require significant gymnastics to keep the client and server state in sync. While this has been open since 2018, we're finally getting some attention on it internally & I expect quick progress to be made—relatively speaking. |
BetaWas this translation helpful?Give feedback.
All reactions
👍 1😕 1
-
@jamesdaniels It's been a year since the last update. Any chance official SSR + Auth will be looked at soon? |
BetaWas this translation helpful?Give feedback.
All reactions
👍 8
-
We now haveFirebaseServerApp, you can combine this with Service Workers to pass an authorization header!https://firebase.google.com/docs/auth/web/service-worker-sessions#web-namespaced-api_5 Added to the documentation herehttps://github.com/angular/angularfire/blob/master/docs/auth.md#server-side-rendering |
BetaWas this translation helpful?Give feedback.
All reactions
-
This Angular team is hoping to allow this solution to work in dev-mode sometime after v18 is released |
BetaWas this translation helpful?Give feedback.
All reactions
-
This doesn't work in Firefox. Even in Firebase documentation site, icons are not loading in Firefox |
BetaWas this translation helpful?Give feedback.
All reactions
-
Greetings, I am a user migrating to angular and I just found this issue for a dashboard app that we are building I just found that flicker behavior for auth routes and ended in this thread discussion how this use case is being handled nowadays? Is it’s possible to disable SSR with angular 19 for protected routes in the meantime ? |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
Yes, quite easily in fact. Just ask Copilot how to do it and it’ll walk you through how to setup the route. You pretty much just declare ssr: false in the route object. GPT 4.1 model does a very good job of explaining how things like this work. |
BetaWas this translation helpful?Give feedback.
All reactions
-
Hi@MarshallBelles excuse me, but one of the reasons I am also researching by my own is because LLMs like Claude and gpt 4.1 tried approaches that didn’t deliver the expected behavior the code generated by LLMs for the guards is the same, inject the auth service in the guard, take the user and map the result within the redirection But this approach is broken when the request is handled by the server, the user is always null even if the user was previously authenticated |
BetaWas this translation helpful?Give feedback.
All reactions
This discussion was converted from issue #1500 on December 10, 2020 02:46.
