Skip to content

Instantly share code, notes, and snippets.

@dig3
Last active Apr 19, 2018
Embed
What would you like to do?
Angular.js ES6 Login example
'use strict';
const TOKEN_KEY = 'auth.token';
class AuthService {
constructor ($window) {
this.$window = $window;
}
isAuthenticated () {
var credentials;
credentials = this.getCredentials();
return !!credentials.token;
}
setCredentials (token) {
this.$window.localStorage.setItem(TOKEN_KEY, token);
}
cleanCredentials () {
this.$window.localStorage.removeItem(TOKEN_KEY);
}
getCredentials () {
var token;
token = this.$window.localStorage.getItem(TOKEN_KEY);
return {
token: token
};
}
}
AuthService.$inject = ['$window'];
export default AuthService;
'use strict';
// Workaround for not losing the this binding in methods
let self;
class AuthInterceptor {
constructor ($location, $q, ConfigService, AuthService) {
this.$location = $location;
this.$q = $q;
this.configService = ConfigService;
this.authService = AuthService;
this.API_LOGIN_URL = `${ConfigService.apiBase}/login/`;
self = this;
}
request (config) {
var canceller;
if (config.url.search(self.configService.apiBase) !== -1 &&
self.authService.isAuthenticated()) {
config.headers.Authorization = `Token ${self.authService.getCredentials().token}`;
} else if (config.url.search(self.configService.apiBase) !== -1 &&
config.url !== self.API_LOGIN_URL) {
canceller = self.$q.defer();
config.timeout = canceller.promise;
canceller.resolve(`Cancelled request to ${config.url} because we do not have credentials`);
self.authService.cleanCredentials();
self.$location.url('/login');
}
return config;
}
responseError (rejection) {
if (rejection.config.url.search(self.configService.apiBase) !== -1 &&
rejection.status === 401) {
// TODO: redirect parameter for login
self.authService.cleanCredentials();
self.$location.url('/login');
}
return self.$q.reject(rejection);
}
static factory ($location, $q, ConfigService, AuthService) {
return new AuthInterceptor($location, $q, ConfigService, AuthService);
}
}
AuthInterceptor.factory.$inject = ['$location', '$q','ConfigService', 'AuthService'];
export default AuthInterceptor.factory;
'use strict';
var ConfigService = {
apiBase: 'http://192.168.20.10/api'
};
export default ConfigService;
'use strict';
import {
AuthService, AuthInterceptorFactory, ConfigService, LoginService, NotifyService
} from './services';
import LoginCtrl from './login.controller';
var dependencies = [
'ngAnimate',
'ngTouch',
'ngSanitize',
'ui.router',
'ui.bootstrap',
'cgNotify',
];
angular.module('Webapp', dependencies)
.service('AuthService', AuthService)
.service('LoginService', LoginService)
.factory('AuthInterceptor', AuthInterceptorFactory)
.service('NotifyService', NotifyService)
.value('ConfigService', ConfigService)
.controller('LoginCtrl', LoginCtrl)
.config(($stateProvider, $urlRouterProvider) => {
$stateProvider
.state('login', {
url: '/login/',
templateUrl: 'login.html',
controller: 'LoginCtrl as vm'
});
$urlRouterProvider.otherwise('/');
})
.config(($httpProvider) =>
$httpProvider.interceptors.push('AuthInterceptor')
)
.config(($locationProvider) =>
$locationProvider.html5Mode(true)
)
// Fix abstract states
.run(($rootScope, $state, $stateParams, notify) => {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
notify.config({
duration: 1000 * 5, // 5s
templateUrl: 'app/components/common/notify.html'
});
});
'use strict';
class LoginCtrl {
constructor ($state, NotifyService, LoginService) {
this.$state = $state;
this.notifyService = NotifyService;
this.loginService = LoginService;
this.loginInProgress = false;
}
login () {
this.notifyService.closeAll();
this.loginInProgress = true;
this.loginService.login(this.email, this.password).then(
() => {
this.loginInProgress = false;
this.$state.go('dashboard');
},
(error) => {
this.loginInProgress = false;
this.showErrors(error);
}
);
}
showErrors (error) {
this.errors = error;
this.notifyService.error(error);
}
}
LoginCtrl.$inject = ['$state', 'NotifyService', 'LoginService'];
export default LoginCtrl;
<div class="login">
<div class="back-layer"></div>
<div class="container">
<header class="row text-center">
<h1>R</h1>
</header>
<form class="col-md-4 col-md-offset-4">
<div class="form-group">
<input type="email" class="form-control" id="email" placeholder="email"
ng-model="vm.email">
</div>
<div class="form-group">
<input type="password" class="form-control" id="password" placeholder="password"
ng-model="vm.password">
</div>
<button type="submit" class="btn btn-default" ng-click="vm.login()">Login</button>
<span class="glyphicon glyphicon-refresh glyphicon-spin ng-hide" ng-show="vm.loginInProgress" aria-hidden="true"></span>
<a class="text-link" ui-sref="passwordReset">Forgot your password?</a>
</form>
</div>
</div>
'use strict';
class LoginService {
constructor ($http, $q, $state, ConfigService, AuthService) {
this.$http = $http;
this.$q = $q;
this.$state = $state;
this.configService = ConfigService;
this.authService = AuthService;
if (AuthService.isAuthenticated() &&
($state.current.name === 'home' || $state.current.name === 'login')) {
$state.go('dashboard');
}
if (!AuthService.isAuthenticated() && $state.current.name !== 'home' &&
$state.current.name !== 'login') {
$state.go('login');
}
}
login (username, password) {
/*jshint camelcase: false */
this.authService.cleanCredentials();
return this.$http.post(`${this.configService.apiBase}/login/`, {
email: username,
password: password
})
.success(data => {
this.authService.setCredentials(data.token);
this.signalsService.emit('renooit:login', username);
})
.catch(error => this.$q.reject(error.data.non_field_errors[0]));
}
logout () {
return this.$http.get(`${this.configService.apiBase}/logout/`)
.success(() => {
this.authService.cleanCredentials();
this.$state.go('login');
})
.catch(error => this.$q.reject(error.data));
}
}
LoginService.$inject = [
'$http', '$q', '$state', 'ConfigService', 'AuthService'
];
export default LoginService;
'use strict';
class NotifyService {
constructor (Notify) {
this.notifyService = Notify;
}
info (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-info ' + (config.classes || '');
return this.notifyService(config);
}
warn (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-warning ' + (config.classes || '');
return this.notifyService(config);
}
error (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-danger ' + (config.classes || '');
return this.notifyService(config);
}
success (message, config) {
config = config || {};
config.message = message;
config.classes = 'alert alert-success ' + (config.classes || '');
return this.notifyService(config);
}
notify (config) {
return this.notifyService(config);
}
closeAll () {
return this.notifyService.closeAll();
}
}
NotifyService.$inject = ['notify'];
export default NotifyService;
'use strict';
import AuthService from './auth';
import ConfigService from './config';
import LoginService from './login';
import AuthInterceptorFactory from './authInterceptor';
import NotifyService from './notify';
export {
AuthService,
ConfigService,
LoginService,
AuthInterceptorFactory,
NotifyService
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment