As my App frontend would be in angular. Below is a flow I have considered for the webapp.
User types in the browser http://www.example.com
Server serves a dummy page with no HTML with the only javascript in angular
Now in the code client makes an ajax http get request to may be http://www.example.com/start
Now if the user is logged in server sends a JSON response with the user info
for angular to route into the users homepage. Otherwise, an appropriate response is sent and angular routes into the sites normal homepage with options to log in.
As I am new in angular , I was asking is this a good design and if not how do experts do it?
My problem is not the authentication , my problem is , when I serve static page I have to pass the user info to the client somehow. When client types it in a browser url bar , I don't have any way to capture the response in a javascript code. That's why I have to send a dummy page first so that I can capture create an ajax request to capture the responses in javascript and act accodringly
And also in the angular $http.get does angular automatically sends the previous session info(cookies) or I have to explicitly send it ?
I am using express,nodejs as server in my backend.
Server serves a dummy page with no HTML with the only javascript in angular
You should really read a little bit about AngularJS before you start trying to build out a frontend implementation with it - most specific single-page application design.
This is a great tutorial for building a single page app with AngularJS.
Essentially, you'll need to render some HTML just to load the Angular application and controller(s) required to validate a user's logged in status.
Borrowing some principles from mobile-first design, if you design your interfaces to first look great without data - you'll have a decent experience between #3 and #4 while your AngularJS controller decides whether to redirect the user or adjust $scope to affect the UI in some way based on your business logic.
You can use a ton of different treatments for #3 to communicate to the user the status of the application (in terms of verifying their login, re-routing them to some secure area, or declining their access)
It's definitely possible to do this, but I would recommend against it. Depending on your user base, there are still enough places in the world and devices with network latency and poor rendering capability, so I would not recommend a completely 'empty' page load w/o javascript. At a minimum, have some static welcome text or something that gets replaced when your angular app is done loading.
The cookies should get passed if you configure it correctly, but I tend to use token-based auth for single page apps.
Related
I have to create a SPA with Angular 8.
In the SPA I will have a component with a form that can only be seen if the user has permissions.
For this I had planned to use a route guard, the problem is that the guard runs in the client's browser, which does not guarantee that the component of the form is not seen by a malicious user (for example, editing the js).
There will be security in the RestAPI backend when receiving the form data (permission check and so on), but I need to make sure that the form cannot be seen by anyone who does not have permissions.
Is there a way to efficiently block the visualization of an angular component?
There is no denying that you client side code can not be accessed by malicious code alteration.
You can not do anything about it, as SPA code relies on front end so if you know the variables and can alter the functions from lets say console or otherwise, there is nothing you can do.
As far the access control goes or blocking UI elements goes, you can have strong back-end which will not authorized unauthorized access. This way only UI can be seen but the data required to function that UI will not be visible (due to back-end access control).
You can think it in logical way,
If the sensitive data is not visible then no problem if UI element is visible.
If some action button is visible to malicious user, as to perform this action you need back-end, this won't work as the malicious use wont have access to end endpoint.
Bottom line is your band-end should be very strong to handle authorized requests and separate itself from unauthorized requests.
I'm currently playing around with a KnockoutJS SPA template in ASP.NET Core 2.1, and I managed to implement an authorization flow exactly as this one which was made in Angular:
https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login
As you can see in their User front-end service, basically the only check for whether the user is logged in on the client side is the check if the "auth_token" key exists in the client's local storage:
https://github.com/mmacneil/AngularASPNETCore2WebApiAuth/blob/master/src/src/app/shared/services/user.service.ts
this.loggedIn = !!localStorage.getItem('auth_token');
// ?? not sure if this the best way to broadcast the status but seems to resolve issue on page refresh where auth status is lost in
// header component resulting in authed user nav links disappearing despite the fact user is still logged in
Simply put, anyone can open up the browser local storage and insert a random string with the "auth_token" key and they'll be able to see everything admin-related in the UI (even though they will fail on API requests).
Can someone suggest a better flow for this? Or is the only option to send a "log in request" to the API, whenever an admin page is "opened"?
P.S. I am relatively new to the authentication schemes front, should JWT perhaps not be used for client-side content validation?
Considering JWT best practices, all your validations should be done in your back-end, since any validation coded in your web app could be read by any of your clients, resulting in a huge security flaw: anyone would know how to create a valid JWT for your application.
Is it a big problem to be possible to see your admin-related UI, even without any data? Considering that all of the routes which can return sensitive data are protected by JWT authorization, if a user access any pages or parts of your UI which require data, they would trigger a request to retrieve it, which would probably return a 401 (Unauthorized) HTTP status, or similar. A common front-end practice in these situations is to erase client user data, and redirect to a login page.
So, a typical flow would be:
User inserts a fake access token into their storage
User opens an admin page/ui which uses sensitive data in any way (showing, using for any internal logic, etc)
Web app does a request to the API requesting data
API returns a response which will be interpreted as an authorization error
Web app receive the API response, erase user access token and redirect them to its login page
In most cases, this entire flow will happen fast enough to block your user to further interact and explore your web app.
Would be better if you provide more information about your scenario, so anyone could understand if your worries are something that needs to be considered and truly solved. However, in most cases, the behavior above is accepted.
I am almost finished with a SPA application using AngularJS and Bootstrap. So far, I got everything working as desired, except for one thing: Proper handling with the users acts on the Browser's back or refresh buttons.
All the sub-pages within the application have buttons/links to the pages the user may switch to. Still, the application should handle properly back and refresh browser buttons. I should add that there is a login process to enter the application.
Also, all the critical information is stored under $rootScope, so everything is lost when the user refreshes and, in some cases, when he acts on the back button the results are not as desirable.
I actually have two questions:
What is the widely accepted standard behavior of applications like mine when browser buttons are acted on? (remember, there is a login process to begin with).
How should I start tackling the implementation of this approach?
One option I was thinking, is to intercept the request, warn the user that the action will log him off, and if the user cancels, force the browser to ignore the request (not sure this is possible).
Client side routing, each view in the application should have a URL. This week allow the browser buttons to work as expected, and gives your users the opportunity to link directly to a view.
The most commonly used client side router for angular is angular ui-router - https://angular-ui.github.io/ui-router
What is the widely accepted standard behavior of applications like
mine when browser buttons are acted on? (remember, there is a login
process to begin with).
If you are using REST services,
Store authentication token in your local storage or in a cookie
When user refresh the page send a request to server and fetch user information
If the request result in 401 then show login screen
This is one of sample applications I have done with this approach.
It has been some time now that i am learning and using angularjs framework, and although some of it's features are truly awesome, it seems to me as if it's key features are a bit problematic for authentication based applications.
Let's look at an example. Let's say i have a website that has a user login, and once the user is logged in he can click on a link to his/hers dashboard page. On the dashboard the user can see some private data. Now, the way i'm used to do it, is run some script on the server side and then if a user is connected, return some HTML, if no then redirect the user to another location. The way angularjs encourages me to do it is by using the route feature, say like this:
when('/dashboard', {
templateUrl: 'dashboard.html',
controller: 'DashboardController'
})
This way, in case a user is not connected, angularjs will first fetch the template HTML, then the controller will fetch some data and receive an authentication error, then redirect the route to another location. To me it seems like a worse solution for more than one reason:
1) First of all, my HTML gets exposed to everyone. Although this isn't devastating, it just seems like a bad security practice (imagine that you do not even have a facebook account, but still you can see all of facebook pages HTML, and even worse, all the objects and fields of the like for example user.accessToken).
2) I would make a larger number of requests to the server, first one to fetch the template, second for authentication validation and data, third and probably fourth for the redirection. I assume angularjs cache the templates so maybe the actual number of requests is smaller than i mentioned, still, dealing with all this on the server side is only one request - and like angularjs, it can also not load the entire page but only the needed HTML throw AJAX. My case here is arguable, but still, something about it seems wrong.
3) This is maybe the most important issue for me. Everything i do on the server side has to be pasted on the client side. For example, the routing feature must be clear on the server side as will as on the client side - in case the user enters directly to some inner page in my application, or through routing in the application links. This means that every time a change something in my routing configuration, i have to do it once in the server side, and once in the client side - which also seems to me like a bad practice and modularity of my code.
Is angularjs not recommended for these kind of applications? Should i use angularjs features that complement my applications (like controllers, variable binding and so on) but disregard and ones that doesn't (like routing)?
Do i look at it the wrong way?
You aren't looking at it the wrong way, just from a different perspective. You aren't use to developing SPA's so this is normal.
1) Sure HTML gets exposed to everyone, but that is just a template. It just contains the html template, not the specific data related to everyones facebook profile. The server controls the data that is returned to the user and it would only return the data that the user had access to see. Really this is no different to a non SPA except for the amount of data that is sent back and forth.
2) For a normal app you would first have to request the login page, then the data would be posted to the server and then a redirect would occur. This is 3 requests. With angular it would be one for the first load, second for the login view template, then third to post login data, then fourth to get the main logged in view and fifth for data required for the view. This is only two more. After that to login, if the user clicks log out and then login again it would only be two requests vs three, or if they close the tab and come back it would be 3 requests. In other words it's not that much difference. For most scenarios it will be the same amount of requests, if not less after caching.
3) The way routing works in a SPA is it only happens on the client. There is no need to have it also on the server. Just re-write the url for all request to return index.html and then angular routing will take care of the rest.
In regards to it being recommended. There are really no such recommendations. It's up to you. There are advantages and disadvantages with both. Most of the disadvantages of Angular would be related to learning curve.
Yes, you do look at it the wrong way. You mix up client- and server side issues.
Your proposed solution for authentication is, as you already said so yourself, bad from a security point of view. Delivering your HTML to the user although he/she is not authenticated is a bad idea.
Authentication always has to be done on the server side. Do not ever trust the client. That's why when you have have an unauthenticated user requesting your restricted-access dashboard.html, you sent back some HTTP error (typically 401 or 403, depending whether the user is unauthenticated or not authorized). This way, an unauthenticated user will never see the dashboard.html and your problems 1 and 2 are solved.
Your point 3 is another matter, but also invalid. There is no reason why your client and server side should have the same routing features. Routing should be up to the client-side in most circumstances. E.g., if your user manually enters http:://mydomain.org/subsite, the server redirects him to http:://mydomain.org, where AngularJS uses the appropriate routing.
So your points are not really about AngularJS being a problem for applications requiring authentication. As a matter of fact, there are many web apps out there with authentication using AngularJS. So as conclusion: No, you can use AngularJS as much as any other JavaScript technology for authenticated sites. However, if it is "recommended" (for your project) is another matter, which depends on many more factors and is beyond the scope of SO.
I have an AngularJS app running on a node/express backend. I'm using passport for user authentication.
When a user signs in or signs up, my angular controllers communicate with express via $http ajax/xhr calls. The form data is sent, node/express/passport process the data, and they return json data with the user's info (i.e. username).
Angular then uses the user info to update my templates, i.e. {{user.username}}
The problem is that if the user refreshes the entire page, Angular loses this user information. They're still logged in - req.user still contains their info - but angular doesn't know about it.
I'd like to avoid an ajax call just to check if the user is logged in. That'll be an extra http call every new visit...
I can pass the user data to the jade template directly, but that can't be updated by angular later.
I prefer ngStorage
Just check this sample example given below, enter anything you want into the text field and refresh the browser and see
Working Demo Preview
JSFiddle
Since An AngularJS module that makes Web Storage working in the Angular Way. Contains two services: $localStorage and $sessionStorage.
Differences with Other Implementations
No Getter 'n' Setter Bullshit - Right from AngularJS homepage: "Unlike other frameworks, there is no need to [...] wrap the model in accessors methods. Just plain old JavaScript here." Now you can enjoy the same benefit while achieving data persistence with Web Storage.
sessionStorage - We got this often-overlooked buddy covered.
Cleanly-Authored Code - Written in the Angular Way, well-structured with testability in mind.
No Cookie Fallback - With Web Storage being readily available in all the browsers AngularJS officially supports, such fallback is largely redundant.
I think the easiest way to solve your problem is to use ngCookies.