Additional Topics
Getting the Current User
We didn't use the currentUser
function in our Auth
service, but it's a great way to get the current user's data without making another request to the server, since it's already encoded in the token. This is also why we ensured that the password wasn't sent back to the server, since the hash could have been decoded and visible!
Making Queries to other APIs
It's possible for an application to query multiple different APIs, such as a Node backend, a weather API, and a recipe API. In that case, we need to alter our AuthInterceptor so it doesn't send our authentication data to these other APIs! Not only would that be unwise in terms of security, but applications often give error messages when invalid tokens are passed.
We can adjust the AuthInterceptor
by having a blacklist/whitelist of endpoints. Here's an example of AuthInterceptor
with a blacklist.
//...
.factory('AuthInterceptor', ['Auth', function(Auth) {
// if querying other APIs, add URLs to this array
var excludedEndpoints = [
'https://swapi.co/api/films'
];
return {
request: function(config) {
var token = Auth.getToken();
var excludedEndpoint = excludedEndpoints.indexOf(config.url) > -1;
if (token && !excludedEndpoint) {
config.headers = config.headers || {};
config.headers.Authorization = 'Bearer ' + token;
}
return config;
}
}
}])
Note that for a whitelist, we'd have to account for URLs that match a particular pattern, like /api/recipes/1
, /api/recipes/2
, etc. This would be a good application of regular expressions.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
Making Alerts
Now that authentication has been set up, what about those cool Bootstrap alerts? Since authentication involves going from controller to controller, we'll need yet another service in order to add Bootstrap modals to our page. Here's an example service.
//..
.factory('Alerts', [function() {
var alerts = [];
return {
clear: function() {
alerts = [];
},
add: function(type, msg) {
alerts.push({type: type, msg: msg});
},
get: function() {
return alerts;
},
remove: function(idx) {
alerts.splice(idx, 1);
}
}
}])
Remember IIFEs (Immediately-Invoked Function Expressions)? In a sense, this factory acts like one! The alerts
array is encapsulated and can only be altered through a set of endpoints:
- clear
- add
- get
- remove
Because Alerts
is a service, a singleton, and able to be injected into controllers, Alerts
will be our app-wide container for storing alerts.
Let's try together: Using the Alerts
service provided above, incorporate alerts into the Secret Recipes app. Additionally, try to add ng-show and ng-hide directives for the links in the navbar. You'll need to keep a few things in mind:
- How will an alert be added after signup, login, and logout?
- How will the alerts be displayed? (May benefit to make an Alerts controller with a template, similar to the
NavCtrl
) - Can we use UI Bootstrap to provide additional functionality?