Авторизация пользователей с AngularJS и Firebase
В прошлой статье, я рассказывал о Firebase. Сегодня я хочу рассказать как я организовал авторизацию пользователей с использованием AngularJS и Firebase.На данный момент я работаю, в свободное время над своим проектом, если в вкратце, то это сервис для создания прототипов SPA-приложений, думаю в скором времени я смогу расказать о нем больше, но пока только об авторизации. Почему я выбрал Firebase? Все просто, я очень ленивый программист и не люблю писать велосипеды, а данный сервис предлагает кучу готовых решений среди которых и авторизация и регистрация пользователей.
Для основы проекта я использую ngBoilerplate, так считаю его достаточно удачной сборкой не требующей каких-то особых доработок. В сборке предустановлены Twitter Bootstrap, Angular UI, Angular Bootstrap, Font Awesome и LESS. Также замечательно настроен Grunt и Bower. Для установки и запуска чистого приложения, нужно всего лишь выполнить следующие команды:
$ git clone git://github.com/joshdmiller/ng-boilerplate $ cd ng-boilerplate $ sudo npm -g install grunt-cli karma bower $ npm install $ bower install $ grunt watch Что-то я отошел немного от темы, продолжим. В проекте я создал модуль аутентификации и назвал его, как ни странно, Auth. Вот собственно так он и выглядит:
angular.module ('Auth', [ 'firebase' ])
.service ('AuthService', [ '$rootScope','$firebase', '$firebaseAuth', '$location', '$q', function AuthService ($rootScope, $firebase, $firebaseAuth, $location, $q){ var firebaseObj = new Firebase ('https://your-firebase-app.com/'); var userStorageKey = 'authUser'; var authUser = $.jStorage.get (userStorageKey) || { status: false, data: false };
return { createUserByEmail: function (email, password){ var deferred = $q.defer (); firebaseObj.createUser ({ email: email, password: password }, function (error) { if (error === null) { deferred.resolve ({ status: true }); } else { deferred.resolve ({ status: false, error: error }); } });
return deferred.promise; }, signInUserByEmail: function (email, password){ var deferred = $q.defer (); firebaseObj.authWithPassword ({ email: email, password: password }, function (error, data) { if (error === null) { // user authenticated with Firebase authUser = { status: true, data: data }; deferred.resolve (authUser); $.jStorage.set (userStorageKey, authUser); } else { deferred.resolve ({ status: false, error: error }); } });
return deferred.promise; }, changeUserPass: function (email, password, newPassword){ firebaseObj.changePassword ({ email: email, oldPassword: password, newPassword: newPassword }, function (error) { if (error === null) { console.log («Password changed successfully»); } else { console.log («Error changing password:», error); } }); }, resetAndSendPassword: function (email){ firebaseObj.resetPassword ({ email: email }, function (error) { if (error === null) { console.log («Password reset email sent successfully»); } else { console.log («Error sending password reset email:», error); } }); }, deleteUser: function (email, password){ firebaseObj.removeUser ({ email: email, password: password }, function (error) { if (error === null) { console.log («User removed successfully»); } else { console.log («Error removing user:», error); } }); }, getUserState: function (){ //console.info (Date (authUser.data.expires));
console.info (authUser); if (authUser.data){ var data = firebaseObj.getAuth (); authUser = { status: data? true: false, data: (data == null) ? {} : data }; $.jStorage.set (userStorageKey, authUser); } return authUser.status; }, logOut: function (){ $firebaseAuth (firebaseObj).$unauth (); $.jStorage.deleteKey (userStorageKey); $rootScope.$userState = this.getUserState (); }, getAuthUser: function (){ return authUser.data; } }; }])
.directive ('signInForm', [ '$rootScope', 'AuthService', '$location', function ($rootScope, AuthService, $location){ return{ restrict: 'A', templateUrl: 'auth/templates/sign-in.tpl.html', link: function (scope, element, attrs){ scope.userEmail = ''; scope.userPassword = ''; scope.userState = AuthService.getUserState ();
scope.signInUserByEmail = function (){ AuthService.signInUserByEmail (scope.userEmail, scope.userPassword) .then (function (response){ scope.userState = AuthService.getUserState (); if (scope.userState) { alert ('You are logged in'); $location.path ('profile'); } else{ alert ('Incorrect user email or password'); } }); }; } }; }])
.directive ('signUpForm', [ '$rootScope', 'AuthService', '$location', function ($rootScope, AuthService, $location){ return{ restrict: 'A', templateUrl: 'auth/templates/sign-up.tpl.html', link: function (scope, element, attrs){ scope.userEmail = ''; scope.userPassword = ''; scope.facebookEnabled = false; scope.userState = AuthService.getUserState (); scope.isRegistered = false;
scope.createUser = function (){ AuthService.createUserByEmail (scope.userEmail, scope.userPassword) .then (function (response){ if (response.status){ alert («Congratulations! You’ve successfully signed up. You can authorize»); scope.isRegistered = true; } else{ alert (response.error); } }); }; } }; }]) ; Он состоит из трех частей: сервис (AuthService) и две директивы (одна для формы логина — signInForm, а вторая для регистрации — signUpForm). Директивы особого интереса не представляют, нам интересен сервис, в котором все и происходит. Внутри сервиса есть ряд функций:
createUserByEmail — создает нового пользователя используя email signInByEmail — авторизация пользователя по email changeUserPass — функция для изменения пароля resetAndSendPassword — тоже функция для изменения пароля, но отличается тем, что старый пароль будет сброшен, а новый придет пользователю на почту deleteUser — удаление пользователя getUserState — функция проверяющая авторизован пользователь или нет и возвращает его состояние logOut — это логаут (спасибо кэп) getAuthUser — возвращает данные авторизованного пользователя. В директивах можно увидеть простую реализацию авторизации и регистрации пользователя.
Также, в коде можно увидеть, что я решил использовать jStorage для хранения данных о авторизованном пользователе. Выбор на него пал потому что он простой и замечательно поддерживается разными браузерами (даже IE6).
Ну это собственно и все что нужно для авторизации/регистрации пользователей используя Firebase. Также есть возможность очень просто добавить авторизацию/регистрацию с использованием социальных сетей (Google, Facebook, Twitter, GitHub) для этого всего лишь нужно зайти на страницу администратора на сайте Firebase, отметить несколько чекбоксов и указать ключи к своим приложениям.
Больше я не знаю что написать, по этому буду рад ответить на любые ваши вопросы в комментариях. Советам и пожеланиям тоже буду очень рад.
