ionic app authenticationionic authenticationionic framework tutorialionic loginIonic Platform authenticationionic signinionic tutorial
Add Ionic Platform authentication to your Ionic App
Introduction
So, here’s the deal, Authentication is a key component for your app, it will enable you to build a relation with your users.
Sign up or Registration, Sign in or Log in, you name it, these are the key to engage with users. Whether you want users to participate by leaving comments, blogging, leaving messages onto boards, posting photos or building a personal network - participation needs to be attributed and/or associated with the user for purposes of building community and reputation, or building up a personal profile or knowledge base. You need to build authentication the right way!
BaaS/PaaS Authentication
Advantages of using a PaaS:
- Update and Maintenance of database tools, systems and infrastructure is full responsibility of the PaaS Cloud Provider.
- Some PaaS providers give developing options to multiple platforms: mobile, browser, among others.
- Cloud PaaS provider can deliver better security measures than the existing software.
- There’s no need to manage the introduction of new versions of software or code. This is handle by the Cloud PaaS provider.
- There’s no need to supply servers or to manage the underlying data center.
Without further ado, let’s get our hand on with the code!
Hands on!
Remember ... you will need:
- You need an Ionic app where you will integrate this login. You can either use a blank app, or an existing one.
- An Ionic Platform account. If you haven't created an Ionic Platform account yet, you will need to sign up.
Ad time!: If you are looking for a beautiful starter app with login UI/UX you must have a look at our beautiful mobile themes, templates & components. Specially our Logins Category.
Setup
Install Ionic
You can find the Ionic official installation documentation here.
Follow these links if you want more information on how to get started:
Other Dependencies
We are going to use the
ionic-platform-web-client
library to communicate our app with the Ionic Platform services (in our case the User Authentication service).
Add the dependency to your
bower.json
file and then run bower install to install it, or you can run ionic add ionic-platform-web-client and that will handle the installation also.Step 1: Hook up our App with Ionic Platform
After following the setup you should have an ionic app with the dependencies installed. Now we need the Platform to assign your app a unique
app id
and app key
. To do that, you should run the ionic io init command.
NOTE: The last step is critical, if we install the
ionic-platform-web-client
but don't init, then we may find some bugs when serving the app.
Finally, to see the current state of the project, run ionic serve
Step 2: Ionic Templates & AngularJS Navigation
For this example app we are going to build a simple navigation schema that will enable us to have both login and signup views, and only one authenticated view with the user profile information. This user view will be only accessible for authenticated users.
This image illustrates the navigation between views

The app will have two main nodes in the navigation, one for the auth section of the app (login, signup views) and other for the main section of the app (user view).

To achieve this, we are going to:
- Add
www/templates/auth/tabs.html
with simple tabbed navigation layout for the login and signup views - Add
www/templates/auth/login.html
with basic login view layout - Add
www/templates/auth/signup.html
with basic signup view layout - Add
www/templates/app/tabs.html
with simple tabbed navigation layout for the user view - Add
www/templates/app/user.html
with basic user details view layout - Update
www/js/app.js
with app’s desired routing - Update
www/js/controllers.js
with a basic controllers for each view
App Routes (js/app.js
)
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('auth', {
url: '/auth',
abstract: true,
templateUrl: 'templates/auth/tabs.html'
})
// Each tab has its own nav history stack:
.state('auth.login', {
url: '/login',
views: {
'tab-login': {
templateUrl: 'templates/auth/login.html',
controller: 'LogInCtrl'
}
},
data: {
authenticate: false
}
})
.state('auth.signup', {
url: '/signup',
views: {
'tab-signup': {
templateUrl: 'templates/auth/signup.html',
controller: 'SignUpCtrl'
}
},
data: {
authenticate: false
}
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/app/tabs.html'
})
.state('app.user', {
url: '/user',
views: {
'tab-user': {
templateUrl: 'templates/app/user.html',
controller: 'UserCtrl'
}
},
data: {
authenticate: true
}
})
;
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/user');
})
Auth Tabbed Navigation Layout (templates/auth/tabs.html
)
<ion-tabs class="tabs-icon-top tabs-color-active-positive">
<!-- LogIn Tab -->
<ion-tab title="Log In" icon-off="ion-person" icon-on="ion-person" ui-sref="auth.login">
<ion-nav-view name="tab-login"></ion-nav-view>
</ion-tab>
<!-- SignUp Tab -->
<ion-tab title="Sign Up" icon-off="ion-person-add" icon-on="ion-person-add" ui-sref="auth.signup">
<ion-nav-view name="tab-signup"></ion-nav-view>
</ion-tab>
</ion-tabs>
Main App Tabbed Navigation Layout (templates/app/tabs.html
)
<ion-tabs class="tabs-icon-top tabs-color-active-positive">
<!-- User Tab -->
<ion-tab title="User" icon-off="ion-ios-body" icon-on="ion-ios-body">
<ion-nav-view name="tab-user"></ion-nav-view>
</ion-tab>
</ion-tabs>
Serve the app with ionic serve and look at the Ionic dev server running on
http://localhost:8100
. There you’ll see the Ionic Auth app with the navigation DONE.Step 3: Login/Signup Layout
The layout of login and signup views is very similar and simple. Note that we added basic
angular.js
form validation using ng-disabled directive and required attributes on the fields just to prevent the submission of the form if the fields are empty.
Login View (templates/auth/login.html
)
<ion-view view-title="Log In">
<ion-content class="padding">
<form name="login_form" class="form-container" novalidate>
<div class="list list-inset">
<label class="item item-input">
<input type="email" placeholder="Email" ng-model="user.email" required>
</label>
<label class="item item-input">
<input type="password" placeholder="Password" ng-model="user.password" required>
</label>
</div>
<button class="button button-block button-positive" ng-click="login(user)" ng-disabled="login_form.$invalid">Login</button>
</form>
<div ng-show="errors">
<p class="message error" ng-repeat="error in errors"><b>[{{error.code}}]</b> {{error.msg}}</p>
</div>
</ion-content>
</ion-view>
Signup View (templates/auth/signup.html
)
<ion-view view-title="Sign Up">
<ion-content class="padding">
<form name="signup_form" class="form-container" novalidate>
<div class="list list-inset">
<label class="item item-input">
<input type="email" placeholder="Email" ng-model="user.email" required>
</label>
<label class="item item-input">
<input type="password" placeholder="Password" ng-model="user.password" required>
</label>
</div>
<button class="button button-block button-positive" ng-click="signup(user)" ng-disabled="signup_form.$invalid">Create Account</button>
</form>
<div ng-show="errors">
<p class="message error" ng-repeat="error in errors"><b>[{{error.code}}]</b> {{error.msg}}</p>
</div>
</ion-content>
</ion-view>
Step 4: App Controllers & Authentication Implementation
The angular.js controllers are the bridge between the views and the main functionality of the app. In this case we choose to add another layer of abstraction. Instead of having the authentication functionality directly in the controllers, we added an AuthService that handles all the authentication communication between our app and the Ionic Platform services.
This way we add independence and if you want to have another provider for the authentication you just have to add a new service with the same signature methods and forget about changing the controllers.
App Controllers (js/controllers.js
)
.controller('LogInCtrl', function($scope, $state, AuthService, $ionicLoading) {
$scope.login = function(user) {
$ionicLoading.show({
template: 'Loging in ...'
});
AuthService.doLogin(user)
.then(function(user){
// success
$state.go('app.user');
$ionicLoading.hide();
},function(err){
// error
$scope.errors = err;
$ionicLoading.hide();
});
};
})
.controller('SignUpCtrl', function($scope, $state, AuthService, $ionicLoading) {
$scope.signup = function(user){
$ionicLoading.show({
template: 'Signing up ...'
});
AuthService.doSignup(user)
.then(function(user){
// success
$state.go('app.user');
$ionicLoading.hide();
},function(err){
// error
$scope.errors = err;
$ionicLoading.hide();
});
};
})
.controller('UserCtrl', function($scope, $state, AuthService) {
$scope.current_user = Ionic.User.current();
$scope.logout = function(){
AuthService.doLogout();
$state.go('auth.login');
};
})
Authentication service using Ionic Platform (js/services.js
)
.service('AuthService', function($q, _) {
this.userIsLoggedIn = function(){
var deferred = $q.defer();
deferred.resolve(Ionic.User.current().isAuthenticated());
return deferred.promise;
};
this.doLogin = function(user) {
var deferred = $q.defer(),
authProvider = 'basic',
authSettings = {
'remember': true
};
Ionic.Auth.login(authProvider, authSettings, user)
.then(function(data){
deferred.resolve(data);
}, function(errors){
var errors_list = [];
if(errors && errors.response && errors.response.responseText)
{
var json_response = JSON.parse(errors.response.responseText);
if(json_response.error.details.length > 0) {
_.each(json_response.error.details, function(err){
var error = {
code: json_response.meta.status,
msg: err.errors[0]
};
errors_list.push(error);
});
}
else {
var error = {
code: json_response.meta.status,
msg: "An unexpected error has occurred"
};
errors_list.push(error);
}
}
else if (errors && errors.length > 0){
var error = {
code: "unknown",
msg: errors[0]
};
errors_list.push(error);
}
else {
var error = {
code: "unknown",
msg: "An unexpected error has occurred"
};
errors_list.push(error);
}
deferred.reject(errors_list);
});
return deferred.promise;
};
this.doSignup = function(user) {
var deferred = $q.defer(),
authService = this;
Ionic.Auth.signup(user)
.then(function(data){
// After signup we should automatically login the user
authService.doLogin(user)
.then(function(data){
// success
deferred.resolve(data);
},function(err){
// error
deferred.reject(err);
});
}, function(errors){
var errors_list = [];
if(errors && errors.response && errors.response.responseText)
{
var json_response = JSON.parse(errors.response.responseText);
if(json_response.error.details.length > 0) {
_.each(json_response.error.details, function(err){
var error = {
code: json_response.meta.status,
msg: err.errors[0]
};
errors_list.push(error);
});
}
else {
var error = {
code: json_response.meta.status,
msg: "An unexpected error has occurred"
};
errors_list.push(error);
}
}
else if (errors && errors.errors && errors.errors.length > 0){
var error = {
code: "unknown",
msg: errors.errors[0]
};
errors_list.push(error);
}
else {
var error = {
code: "unknown",
msg: "An unexpected error has occurred"
};
errors_list.push(error);
}
deferred.reject(errors_list);
});
return deferred.promise;
};
this.doLogout = function() {
Ionic.Auth.logout();
};
})
Step 5: Final details
The last thing we are going to do is to add some code in the app.js file to handle only the authentication views. We will check if the view state requires authentication and if the user is authenticated and based on that decide whether or not show him the view.
App run method (js/app.js
)
.run(function($ionicPlatform, $rootScope, $state, AuthService) {
$ionicPlatform.ready(function() {
AuthService.userIsLoggedIn().then(function(response)
{
if(response === true)
{
$state.go('app.user');
}
else
{
$state.go('auth.login');
}
});
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
if (cordova.plugins.Keyboard.hideKeyboardAccessoryBar) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
// UI Router Authentication Check
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
if (toState.data.authenticate)
{
AuthService.userIsLoggedIn().then(function(response)
{
if(response === false)
{
event.preventDefault();
$state.go('auth.login');
}
});
}
});
})
0 comments