Restrict certain AngularJS routes for given NodeJS route - javascript

I have two routes added to my NodeJS backend server app.js file as follows:
// Add the routes
app.get('/provision', ...);
app.get('/', ...);
Either of these routes gives full access to all the routes defined in AngularJS:
function routes($routeProvider){
$routeProvider
.when('/list',
{
templateUrl: 'sections/list/list.tpl.html',
controller: 'listController',
controllerAs: 'listCtrl'
})
.when('/overview',
{
templateUrl: 'sections/overview/overview.tpl.html',
controller: 'overviewController',
controllerAs: 'overviewCtrl'
})
...
Just for example: I would like to control for "/provision" route in NodeJS to be able to access only "/list" route in AngularJS and for "/" route in NodeJS to be able to access only "/overview" route in AngularJS.
Currently in my code, I am able to access all the AngularJS routes from browser using "/provision" or "/" route defined in NodeJS. I would like to access only certain angularJS routes for "/provision" and the rest with "/" route. How can I control that?

If you're using angular routing, you probably don't need to be using anything but the * route in Node except for api calls. You can use the stateChangeStart lifecycle method to determine if the user should be allowed to an angular route however. Some explanation of how to do this is found here UI- Router -- run function on every route change -- where does the state name live?
So to reiterate you wouldn't use both node and angular to handle routing. You'd have a * route which will allow ui router to handle all of the routing. You can use stateChangeStart to determine if the user is allowed to go where they are trying to go, and if not you can redirect them.

Related

How to check if user is authenticated in AngularJS router?

I have an application set up with the Mean.js yeoman generator. It uses PassportJS to setup local-authentication. This all works great and I understand how to check if a user is logged in from the ExpressJS routes file.
The problem is that most of my page routing is done in the angular routes. I know how to check authentication in the controller with the the following code.
// Projects controller
angular.module('projects').controller('ProjectsController', ['$scope', '$stateParams', '$location', 'Authentication', 'Projects',
function($scope, $stateParams, $location, Authentication, Projects) {
$scope.authentication = Authentication;
But how do I check authentication in the routes. For example in this routes files how would I only allow authenticated users to access the tools html file and redirect users that arent logged in back to the home page:
'use strict';
//Setting up route
angular.module('analysis').config(['$stateProvider',
function($stateProvider) {
// Projects state routing
$stateProvider.
state('imageAnalysis', {
url: '/analysis',
templateUrl: 'modules/analysis/views/tools.client.view.html'
});
}
]);
I know there are similar posts out there but I had trouble understanding many of them. Thanks, I really appreciate any help. I am new to the stackoverflow community and still learning community standards.
At a high level, there are two approaches:
Use your view routing layer (e.g. UI Router) to catch “unauthenticated” state
Use HTTP interceptors to look for requests that have a 401 Unauthorized status, indicating that the user must login (or that their current session has expired)
In practice you’ll probably use a combination of both.
Speaking to the UI Router, there a two of doing this: resolves or events.
Resolves: The UI Router provides a nice feature called resolves, which allows you to provide a promise that must be resolved before the view is rendered. You could create a promise which resolves your user state.
Events: The UI Router provides a $stateChangeStart event, you can observe this event and prevent it if the user is not logged in. You would then send the user to login page. This is a bit more stateful (you have to remember where the user wanted to go in the first place, so that you can redirect after login).
I chose the event approach for my work on the Stormpath Angular SDK because it gives me the flexibility to define authorization on top of authentication.
You may be looking for HTTP Interceptors. Check auth on the requests.
From OneHungryMind:
HTTP interceptors are a great way to define behavior in a single place
for how a request or response is handled for ALL calls using the $http
service. This is a game changer when you want to set an auth token on
all outgoing calls or respond to a particular HTTP status error at the
system level. You can pair interceptors with the incredibly useful
Angular Storage module to cache an authenticated user and retrieve it
the next run time.
There are some good tutorials(1) out there(2)!

Angular redirecting to subdomain for a single route with standard Angular router

I have a page in my Angular app that I need to redirect to a subdomain. So if the user visits /latino, they should be redirected to "spanish.mysite/latino". I am new to Angular and I see the redirectTo function for the router but this will not let me redirect to a subdomain. When I add
redirectTo: "latino.localhost:3000/latino",
The url I get is "http://localhost:3000/latino.localhost/latino". Is it possible to do this without the UI router?
It seems like you want it to go to the "/latino" endpoint. If so, you just need to change your code to:
redirectTo: "latino"
This will give you the url:
localhost:3000/latino
My solution to this was to use an external redirect in a route filter. This is required because the Angular router considers spanish.localhost:3000 to be an external URL due to the subdomain.

Integrating login Authentication module with existing Angular JS application

I have purchases an Angular JS theme and started developing our application. The $routeProvider of that app looks like this:
$routeProvider
.when('/', {
redirectTo: '/dashboard'
})
.when('/:page', {
templateUrl: function($routeParams) {
return 'views/'+ $routeParams.page +'.html';
},
controller: 'PageViewController'
})
.when('/:page/:child*', {
templateUrl: function($routeParams) {
return 'views/'+ $routeParams.page + '/' + $routeParams.child + '.html';
},
controller: 'PageViewController'
})
.otherwise({
redirectTo: '/dashboard'
});
It is a single page Application
Now I need to integrate login authentication module to it. I'm relatively new to AngularJS. I searched and got lot of articles about login, authentication modules for AngularJS application (few good answers in stack overflow as well) , which I could understand how it works.
But I'm not knowing how to make login work together with the existing application. Either having by having 2 different apps (one for login-authentication, and one for main app) or integrating login as separate angular.module in the main app. Please guide me how should I do...
All the examples have only 2 or 3 items in the $routeProvider including login and logout and the main app page. But in this case, main app page itself has many route providers.
I think I have some basic disconnect here. Please help me understanding the disconnect and integrating login-authentication with the existing application.
I don't know what more code components to add. Will share additional code if required.
Thank you.
I think that it could be a long answer if you are searching for a complete solution. What I could say quickly is that, in my opinion, you have to:
create a login page and put it in views folder
create a specific login Controller
add a route to login page before ':/page' route that uses the login Controller you just created
if your application require authentication, you have to edit PageViewController in order to redirect to login page if the current user is not logged yet.
As I said, it's a quick answer in order to the big work you have to do, but I hope you found this useful.
Bye

Angular - UI Router Routes - HTML5 Mode

I'm trying to use HTML5 push state links with my Angular app. What I have is a series of routes similar to the following
$stateProvider.state('product', {
url: '/product/:productCode',
templateUrl: 'product/product.html',
controller: 'ProductCtrl'
}
});
This works when I navigate to [host]/#/product/ABC123 - It displays the url in the browser as /product/ABC123, then when I start clicking through to my other routes (using ui-sref) everything works as expected.
However - I'd like the ability to both refresh the browser, and remain in the same state, as well as be able to copy and paste that link and route to the right state.
eg. If I got to [host]/product/ABC123 - I want to display the content from the #/product/ABC123 route. Currently, this will give me a not found.
I'm using nginx as my app server. I believe I'll have to add something to handle it at that level, but I'm not sure where to start.
The issue you have is that your server does not know how to respond to /product/ABC123.
I am currently using node.js for my backend with angular, and to solve this I return the angular app for all routes, not just the usual root route for example.
So you might have used something like this in the past:
app.get('/', ...);
Which would have returned the angular app just for the root route. Now I use something like:
app.get('*', ...);
Which will return the angular app for all routes.
I should have mentioned that this can act as a catch all placed after other routes such as for static files. Another alternative is to mark all the routes you want specifically for the angular app, eg:
app.get('/', ...); app.get('/product/:productId', ...); etc

Using $stateProvider in Angularjs for different server side route

I planned to add an admin panel which use a different layout template for angularjs and expressjs.
For example, the mean stack now defined to use $stateProvider as route but it will work globally.
$stateProvider.state('access home', {
url: '/home',
templateUrl: '/views/index.html'
})
That means when I call localhost/#/home and localhost/admin/#/home would get the same template url.
But what I want is that the route and admin panel route should not have such conflict and render differently for even the same route.
I am new to use angularjs and please give a help. Thanks a lot!

Categories