Hallo
Ik ben recent begonnen met AngularJS en ben als oefening/freelance een fitness oefeningen & training schema applicatie aan het bouwen. Ik heb hiervoor veel gewerkt in jQuery, en helaas veel codesoep geproduceerd waar ik nu steeds meer achter kom naarmate ik meer lees/ontdek over hoe het wel moet. Ik was al begonnen met die fitness applicatie in jQuery, maar daar werd ik al vrij snel gefrustreerd omdat het weer een codesoep dreigde te worden en ik dus nu mooi een redelijke app kan gebruiken om Angular onder de knie te krijgen.
Ik ben vandaag bezig geweest met een inlog systeem voor deze applicatie, die via JSON Web Tokens een simpele token ophaalt en deze opslaat in de localStorage. Ik heb dit in een Factory geplaatst icm een Interceptor die aan API calls de header toevoegt:
Zoals je misschien wel ziet ben ik nog niet helemaal thuis in Angular; elke feedback is welkom
user.factory.js
auth.interceptor.js
- in de index.config.js
Ik moet nog error handling toevoegen voor het decoderen van de token en nog wat andere kleine dingen, maar dat staat verder op de lijst van todo's.
Welnu, mijn vraag:
Ik heb nu de functie userFactory.isLoggedIn() die ik kan gebruiken om te bepalen of de gebruiker is ingelogd, waarna ik bepaalde delen van de interface kan verbergen en routes kan uitschakelen... dat is het idee.
Nu heb ik bijvoorbeeld een index controller en template waar ik een linkje plaats naar de 'trainings' pagina, die ik wil verbergen als de gebruiker niet is ingelogd:
Ik ben al een aantal dagen fulltime bezig me te verdiepen in Angular en ik kom steeds maar weer dit soort code-constructie technische vragen tegen waar niet tegen op te googlen valt.
Klopt mijn userFactory een beetje?
Zie ik iets over het hoofd?
Hoe kan ik het beste zorgen dat ik de functie userFactory.isLoggedIn() kan gebruiken om te bepalen of ik bijvoorbeeld bepaalde linkjes in de interface wel of niet laat zien?
Hoe kan ik straks het beste het 'permissions' systeem aanpakken: de userFactory heeft ook een 'permissions' array die gevuld is met een aantal acties die de gebruiker wel/niet mag (can_edit_exercise, can_assign_training, etc).. Dat zal waarschijnlijk in de routes moeten worden afgevangen maar ook in de verschillende knoppen in de interface..
Alvast bedankt voor alle hulp
Ik ben recent begonnen met AngularJS en ben als oefening/freelance een fitness oefeningen & training schema applicatie aan het bouwen. Ik heb hiervoor veel gewerkt in jQuery, en helaas veel codesoep geproduceerd waar ik nu steeds meer achter kom naarmate ik meer lees/ontdek over hoe het wel moet. Ik was al begonnen met die fitness applicatie in jQuery, maar daar werd ik al vrij snel gefrustreerd omdat het weer een codesoep dreigde te worden en ik dus nu mooi een redelijke app kan gebruiken om Angular onder de knie te krijgen.
Ik ben vandaag bezig geweest met een inlog systeem voor deze applicatie, die via JSON Web Tokens een simpele token ophaalt en deze opslaat in de localStorage. Ik heb dit in een Factory geplaatst icm een Interceptor die aan API calls de header toevoegt:
Zoals je misschien wel ziet ben ik nog niet helemaal thuis in Angular; elke feedback is welkom
user.factory.js
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
| (function () { 'use strict'; angular .module('fCmsa') .factory('userFactory', userFactory); /** @ngInject */ function userFactory($injector, $q, jwtHelper, $log, URLS) { // Private variables holding the token, the current user and his/her permissions from the token (if available) var _token = _getToken(); var _user = {}; var _permissions = {}; /** * Look for a token in the localStorage -> return token or FALSE (instead of null) when no token is present * @returns {boolean} * @private */ function _getToken() { var token = localStorage.getItem('id_token'); return token != null ? token : false; } /** * When invoked, store a new token in localStorage (for next time) and also locally in this factory * @param newToken * @private */ function _setToken(newToken) { _token = newToken; return localStorage.setItem('id_token', _token); } /** * Decode a JWT with the jwtHelper library and retrieve the payload * @private */ function _decodeToken() { if(_token != false) { var tokenPayLoad = jwtHelper.decodeToken(_token); // The payload is a JSON array with permissions and the currently logged in user _user = tokenPayLoad.user; _permissions = tokenPayLoad.permissions; $log.log(tokenPayLoad); } } // We want to decode this token as this will populate the factory _decodeToken(); return { /** * Get the current user (only if user is initialized * @returns {*} */ getUser: function() { return _user; }, /** * Get the current user-permissions if initialized * @returns {*} */ getPermissions: function() { return _permissions; }, /** * Use this to determine if a user is a guest or not * @returns {boolean} */ isLoggedIn: function() { return _token != false; }, /** * Is used to retrieve the token if available -> used by the auth interceptor */ getToken: function() { return _token; }, /** * Send a request to the API login with email and password to receive a token -> returns object with success true|false * @param email * @param password */ loginAttempt: function (email, password) { // Due to a circular dependency problem with the interceptor (also depends on $http) we manually inject $http here var $http = $injector.get('$http'); // Return a promise with token on success or code+error on error return $http.post(URLS.api + '/login', email, password) .then(function(response) { // Set a new token from now on _setToken(response.data); // Also try to decode this token as this will refresh the user info _decodeToken(); // Return true as the login was a success and the promise was resolved return true; }, function(error) { // Return a rejected promise with throw and pass code + error return $q.reject({ code: error.status, // HTTP status code error: error.data.error // Error message from server }); }); } }; } })(); |
auth.interceptor.js
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| (function() { 'use strict'; angular .module('fCmsa') .factory('authInterceptor', authInterceptor); /** @ngInject */ function authInterceptor(userFactory, URLS) { return { request: function(config) { // Get the token from the userFactory var token = userFactory.getToken(); // Only send the auth header when a call is made to /api and the token has a truth-y value if(config.url.indexOf(URLS.api) === 0 && token) { config.headers.Authorization = 'Bearer ' + token; } return config; } }; } })(); |
- in de index.config.js
JavaScript:
1
2
3
4
5
6
7
| ***** /** @ngInject */ function configJWTInterceptor($httpProvider) { // Push the authInterceptor which will inject the Auth Header to API calls and watch for error responses from the API $httpProvider.interceptors.push('authInterceptor'); } ***** |
Ik moet nog error handling toevoegen voor het decoderen van de token en nog wat andere kleine dingen, maar dat staat verder op de lijst van todo's.
Welnu, mijn vraag:
Ik heb nu de functie userFactory.isLoggedIn() die ik kan gebruiken om te bepalen of de gebruiker is ingelogd, waarna ik bepaalde delen van de interface kan verbergen en routes kan uitschakelen... dat is het idee.
Nu heb ik bijvoorbeeld een index controller en template waar ik een linkje plaats naar de 'trainings' pagina, die ik wil verbergen als de gebruiker niet is ingelogd:
JavaScript:
1
2
3
| <body ng-controller="IndexController as index"> **** <li ng-if="index.isLoggedIn"><a class="caps" ng-href="/trainings" translate="trainings"></a></li> |
Ik ben al een aantal dagen fulltime bezig me te verdiepen in Angular en ik kom steeds maar weer dit soort code-constructie technische vragen tegen waar niet tegen op te googlen valt.
Klopt mijn userFactory een beetje?
Zie ik iets over het hoofd?
Hoe kan ik het beste zorgen dat ik de functie userFactory.isLoggedIn() kan gebruiken om te bepalen of ik bijvoorbeeld bepaalde linkjes in de interface wel of niet laat zien?
Hoe kan ik straks het beste het 'permissions' systeem aanpakken: de userFactory heeft ook een 'permissions' array die gevuld is met een aantal acties die de gebruiker wel/niet mag (can_edit_exercise, can_assign_training, etc).. Dat zal waarschijnlijk in de routes moeten worden afgevangen maar ook in de verschillende knoppen in de interface..
Alvast bedankt voor alle hulp
[ Voor 6% gewijzigd door Edwin88 op 17-04-2016 13:41 ]