I have been attempting to create a script that grabs session data from a PHP API using Angular JS to create authentication.
I have created a factory called User and in my loginController I use User.Initialise() to check whether the session in PHP has a user_id attached to it.
When using User.Initialise() in my loginController (bare in mine my session has a user attached to it) it will use $location.path("/dashboard") to change the route to the dashboard. The dashboard route has a controller that has the variable $scope.UserID which is assigned using User.Session.user_id, however, when I attempt to call User.Session it returns undefined, even though User.Initialise(); assigns it in the loginController.
Can anybody shed some light on this?
var $Gladium = angular.module("Gladium", ["ngRoute", "ngAnimate", "ngSanitize"]);
$Gladium.config(function($routeProvider, $locationProvider){
$routeProvider.when("/",{
templateUrl: "pages/login.html",
controller: "loginController"
}).when("/dashboard",{
templateUrl: "pages/dashboard.html",
controller: "dashboardController"
}).when("/error/:error_code", {
templateUrl: "pages/system_error.html",
controller: "errorController"
});
});
/* Controllers */
$Gladium.controller("dashboardController", function($scope, User){
console.log("Services:");
console.log(User.Session);
});
$Gladium.controller("loginController", function($scope, $location, User){
User.Initialise().then(function(){
$scope.Authenticate = true;
if(User.loggedIn()){
$location.path("/dashboard");
}
});
/* Variables */
$scope.Email;
$scope.Password;
$scope.Login = function(){
if(User.logIn($scope.Email, $scope.Password)){
$location.path("/dashboard");
return true;
}
}
});
$Gladium.controller("errorController", function($scope, $routeParams){
$scope.Errors = {
"request": "We couldn't process that request at this time. Please try again later.",
"unknown": "An unknown error occurred if this is persistant please contact technical support."
};
$scope.currentError = $scope.Errors[$routeParams["error_code"]];
});
/* Factories */
$Gladium.factory("User", function($http, $location){
var Session;
var Error;
return {
Initialise: function(){
return $http.get("core.php?do=getSession").then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Session = requestData.data.data;
}else{
$location.path("/error/request");
return false;
}
});
},
loggedIn: function(){
if(Session["user_id"] != 0){
return true;
}else{
return false;
}
},
logOut: function(){
if(Session["user_id"] != 0 ){
$http.post("core.php",{
do: "logout"
}).then(function(requestData){
if(requestData.data["requestStatus"] == 1){
}else{
}
});
}else{
console.warn("There is no user session to logout.");
}
},
logIn: function(Email, Password){
$http.post("core.php",{
do: "login",
email: Email,
password: Password
}).then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Data = requestData.data;
if(Data["actionStatus"] == 1){
Initialise();
}else{
Error = Data["Error"];
return false;
}
}else{
$location.path("/error/request");
return false;
}
$location.path("/error/unknown");
return false;
});
}
}
});
I think that u just forget to return the Session variable which should be a property of User Service
....
$Gladium.factory("User", function($http, $location){
var Session;
var Error;
return {
// return the Session so it can be accessed via User.Session, or it is a variable in private closure
Session:Session
Initialise: function(){
return $http.get("core.php?do=getSession").then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Session = requestData.data.data;
}else{
$location.path("/error/request");
return false;
}
});
},
....
UPDATE
Sorry the change above won't solve your problem since you are assigning the Session closure variable, which will not change User.Session.In this way it still remains undefined.
There are several ways for you to solve this problem.
One i think that is the most simple is to keep the Session private and access it via a get function User.getSession().
$Gladium.factory("User", function($http, $location){
var Session;
var Error;
return {
// use get function to get Session
getSession:function(){
return Session;
},
Initialise: function(){
return $http.get("core.php?do=getSession").then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Session = requestData.data.data;
}else{
$location.path("/error/request");
return false;
}
});
},
....
In this way u can access your Session by User.getSession().
Related
I want to know how to redirect to another page using Angular Js.
I already follow several questions here and don't find any answer with works successfully
This is my code :
var app = angular.module('formExample',[]);
app.controller('formCtrl',function($scope,$http){
$scope.insertData=function(){
// if($scope.name =='' && $scope.email == '' && $scope.message = '' && $scope.price =='' && $scope.date == null && $scope.client == ''){return;}
$http.post("/php/login.php", {
"email": $scope.email, "password": $scope.password
}).then(function(response, $location){
alert("Login Successfully");
$scope.email = '';
$scope.password = '';
$location.path('/clients');
},function(error){
alert("Sorry! Data Couldn't be inserted!");
console.error(error);
});
}
});
I´m getting this error:
TypeError: Cannot read property 'path' of undefined
You need to inject $location to your controller,
app.controller('formCtrl',function($scope,$http,$location){
You can use a plain JS
window.location.href = '/my-other-page'
Or, if you are using 'ui-router'
$state.reload()
or
$state.go($state.current.name, {}, {reload: true})
don't forget to inject $state into your controller dependencies:
app.controller('formCtrl',function($scope, $http, $state){
You can redirect using $window in your controller.
$window.location.href = '/index.html';
Hope this helps you
Since firebase did their major update, it has been nearly impossible for me to find answers to basic questions. Even using their docs.
My question is how do I allow my users to sign in once on my app and stay logged in indefinitely or for a set amount of time?
Once I have a user logged in, how can I access their data? Like first and last name? Do I have to create a database and link to the userID somehow?
I am also struggling to understand how "firebase.auth().signInWithEmailAndPassword(email, password)" works since I am not providing it my firebase url. is it pulling it from the config obj on the index page?
Here is my angular code:
appControllers.controller('userCtrl', ['$scope', '$rootScope', '$ionicPlatform', '$cordovaDevice', '$mdToast', '$mdBottomSheet', '$timeout', '$stateParams', '$state', 'LogIn', 'SignUp', '$http', '$firebaseAuth',
function($scope, $rootScope, $ionicPlatform, $cordovaDevice, $mdToast, $mdBottomSheet, $timeout, $stateParams, $state, LogIn, SignUp, $http, $firebaseAuth) {
var devid;
$scope.id = "1";
$scope.errorMsg = "";
// timeout to get device ID
$timeout(function() {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log(device.cordova);
$scope.id = $cordovaDevice.getUUID();
return $scope.id;
}
}, 1000);
// watches change in DEVID
$scope.updateID = function() {
devid = $scope.id;
console.log(devid);
return devid;
};
$scope.initialForm = function() {
$scope.moveBox = function() {
// $("#signupbox").fadeOut();
$('#signupbox').animate({
'marginTop': "+=170px" //moves down
});
$timeout(function() {
$state.go('app.signup');
}, 500);
$timeout(function() {
$('#signupbox').animate({
'marginTop': "-=170px" //moves down
});
}, 1000);
} // end animate
// Toast for empty Fields
$scope.showAlert = function(menuName, time) {
//Calling $mdToast.show to show toast.
$mdToast.show({
controller: 'toastController',
templateUrl: 'toast.html',
hideDelay: time,
position: 'top',
locals: {
displayOption: {
title: menuName
}
}
});
} // End showToast.
// check LogIn
var em, pw;
$scope.user = {};
$scope.updateEmail = function() {
em = $scope.user.email;
console.log(em);
return em;
};
$scope.updatePass = function() {
pw = $scope.user.pass;
console.log(pw);
return pw;
};
// Password Validation
$scope.validatePass = function(ppw) {
if (ppw.length < 8) {
$scope.errorMsg = "Password must be at least 8 characters long";
}
};
// start login
$scope.logInNow = function() {
var sdata = {
em: em,
pw: pw
};
if (pw == "" || pw == null) {
$scope.errorSignIn = "Fields cannot be blank";
}
// FIREBASE LOGIN
else {
firebase.auth().signInWithEmailAndPassword(sdata.em, sdata.pw)
.then(function(authData) {
console.log("Logged in as:", authData.uid);
$state.go('app.types');
}).catch(function(error) {
console.error("Authentication failed:", error);
$scope.errorSignIn = "Email or Password is invalid";
});
}
}
};
$scope.initialForm();
}
]);
Staying logged-in forever is default behaviour, but it is all about cookies, so if Ionic clears cookies the user get logout. I'm not into Ionic so I guess you need to figure it out whether it is something with Ionic. Related Ionic blog post. If you want to logout user at some point you can do this by setting a timer and just logout user after X time passed. Note that this is a client-side operation.
In my web app I did something like this:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
$scope.photoURL = user.photoURL;
$scope.name = user.displayName;
$scope.logged_in = true;
} else {
$scope.photoURL = "";
$scope.name = "";
$scope.logged_in = false;
}
});
It works, since every time user enter app the state is changing I always have correct data (Firebase User Interface). I remember there was another way to make it, but I had some issues.
Firebase is first configured and then initialized and every call you do on your app is configured for your project. So yes it is pulling from config.
By the way. Are you using the new docs like https://firebase.google.com/docs/. I am asking because they are actually pretty nice.
I do create a login system into Ionic/angularjs framework.
I would like to store a cookie and set the expires for a long time, so the user does not need to login every time as it is an internal app.
I just add http post to this controller, could not handle the cookie dependencies yet and the cookie creation:
.controller('AppCtrl', function($scope, $ionicModal, $timeout, $http, $location, $state ) { //, $cookieStore, Auth
$scope.loginData = {};
$scope.doLogin = function() {
if(!angular.isDefined($scope.loginData.login)
|| !angular.isDefined($scope.loginData.password)
|| $scope.loginData.login.trim() == ""
|| $scope.loginData.password.trim() == ""){
alert("Digite seu usuário e senha");
return;
}
$http.post('http://www.somedomain.com/somefile.php',$scope.loginData)
.then(
function(result) {
$scope.response = result;
angular.forEach(result.data, function(value, key) {
console.log(key + ': ' + value);
if( value.slice(-1) == 1 ) {
$location.path('/app/playlists');
} else {
$ionicModal.fromTemplate('<button class=button>try again</button>').show();
}
});
});
};
$scope.logout = function() {
Auth.logout();
$state.go("acesso");
};
})
Use angular-local-storage , you can work with setStorageCookie, here is the link to documentation : https://github.com/grevory/angular-local-storage
In angular js I have a routing function that should manage access to routes for admin and non admin users so i used to $routeChangeStart achieve that according to my logic if a user is logged in he can not go to that rout '/' (which is log in page ). but that dose not work. it still can go to login if the URL matches http://localhost:3000/#/
app.run(['$rootScope', 'authService', '$location', function($rootScope, authService, $location){
$rootScope.$on('$routeChangeStart', function(evt, next, curr){
if(authService.AccessPrivilegesAuth()){
if(!authService.AccessPrivilegesAdmin(next.access_level)){
$location.path('categories');
}
}else if(authService.AccessPrivilegesAuth()== false){
$location.path('/');
}
})
}]);
her is the log in controller.
app.controller('LoginController', ['$scope', '$location', 'authService','$cookieStore', function($scope, $location, authService, $cookieStore){
$scope.loginData = {
EmailAddress : "",
password : ""
};
$scope.error; $scope.error_exist = false;
$scope.login = function(){
authService.Login($scope.loginData).success(function(response){
$cookieStore.put('AuthorizationHeader', response.Token);
authService.isAuth = true;
authService.IsAdmin = response.IsAdmin;
var authData = $cookieStore.get('AuthorizationHeader');
console.log(authData);
$location.path('categories');
}).error(function(Error){
$scope.error_exist = true;
switch(Error.ExceptionMessage){
case "201" :
$scope.error = "The emailAddress/password pair don't match an existing member"; break;
case "210" :
$scope.error = "Value cannot be null missing Email Address and/or password."; break;
case "202" :
$scope.error = "The email address you are using isn't confirmed. Please see your inbox for further instructions."; break;
default :
$scope.error = "Error with the server";
}
});
};
}]);
$routeChangeStart has preventDefault() but from what I remember it didn't work. However some time ago I managed to get it working with $locationChangeStart.
$locationChangeStart fires before $routeChangeStart and if it is prevented, $routeChangeStart doesn't fire at all.
Note that I haven't tested this code:
$rootScope.$on("$locationChangeStart", function(event) {
if(notAllowed){
event.preventDefault();
};
});
I'm just trying to get this to work:
.....
.when('/channel/:id/:slug',{
templateUrl:'views/channel/index.html',
controller:'Channel',
publicAccess:true,
sessionAccess:true
})
.....
app.controller('Channel', ['$scope','$routeParams', function ($scope,$routeParams) {
}]);
app.run(function($rootScope, $location, $route) {
var routesOpenToSession = [];
angular.forEach($route.routes, function(route, path) {
console.log(path);
console.log(route);
route.sessionAccess && (routesOpenToSession.push(path));
});
$rootScope.$on('$routeChangeStart', function(event, nextLoc, currentLoc) {
var closedToSession = (-1 === routesOpenToSession.indexOf($location.path()));
if(closedToSession && $rootScope.session.id_user) {
$location.path('/');
}
});
});
why i can't access the page via site.com/channel/9/my-slug also if $rootScope.session.id_user exists and sessionAccess:true ?
i get redirected to / , while any other static url are ok using sessionAccess:true for example channel/staticparam is ok but with dynamic params it won't work
this is the console log result :
fixed sorry for the stupid question:
/*Not logged redirects*/
app.run(['$rootScope','$location','$route', function ($rootScope, $location,$route) {
var routesOpenToPublic = [];
angular.forEach($route.routes, function (route, path) {
if(route.publicAccess){ routesOpenToPublic.push(route.regexp); }
});
$rootScope.$on('$routeChangeStart', function (event, nextLoc, currentLoc) {
var next_url_regexp = nextLoc.$$route.regexp;
//redirect for not logged users users
if(routesOpenToPublic.indexOf(next_url_regexp) < 0){
$location.path('/auth/login');
}
});
}]);
/*Logged redirects*/
app.run(['$rootScope','$location','$route', function ($rootScope, $location, $route) {
if($rootScope.session && $rootScope.session.id_user){
var routesOpenToSession = [];
angular.forEach($route.routes, function (route, path) {
if(route.sessionAccess){ routesOpenToSession.push( route.regexp);}
});
$rootScope.$on('$routeChangeStart', function (event, nextLoc, currentLoc) {
var next_url_regexp = nextLoc.$$route.regexp;
//redirect for not allowed session users
if(routesOpenToSession.indexOf(next_url_regexp) < 0){
$location.path('/');
}
});
}
}]);
i needed to check the route regexp and not the static url path