mean stack login error: no token provided - javascript

Background: I am creating an app using node/express as my backend, mongo as the database, and angular as the front end. I am using jsonwebtoken to authenticate the user. Once the user logs in, a token is stored in the local storage, which is used to authenticate all requests. After the user logs in,
the name and username is retrieved via Auth.getUser(), which is an angular factory method that gets data from the backend. Each request
Problem: I am unable to get the user to redirect to the home page, because the following code does not run:
vm.login = function() {
vm.error = '';
Auth.login(vm.loginData.username, vm.loginData.password)
.then(function(data) {
Auth.getUser()
.then(function(data) {
vm.user = data.data;
});
if (data.success) {
$location.path('/');
} else {
vm.error = data.message;
console.log(vm.error);
}
});
}
I do not get redirected to the homepage, although I also do not get any message either in the dev console or my terminal.
When I check the local storage via the dev console, I do not have the token. However, I am able to login/signup/post data successfully using POSTMAN. I think the problem can be fleshed out via the following steps:
1. The user logs in, and the token is stored in the local storage
2. Auth.getUser() is suppose to request for the user data from the backend.
3.Each request requires the token to be verified via the jsonwebtoken.verify() method.
4.For some reason, the token is not sent to my backend, so this does not run:
api.use(function(req,res,next) {
console.log('someone tried to access a secure page');
var token =
req.body.token || req.param('token') || req.headers['x-access-token'];
if (token) {
//code
} else {
res.status(403).send({ success: false, message: "No Token Provided"});
Here are what I deem the relevant files:
backend:
var mongoose = require('mongoose');
var User = require('../models/user.js');
var Story = require('../models/story.js');
var config = require('../../config/config.js');
var jsonWebToken = require('jsonwebtoken');
var sessionSecret = config.sessionSecret;
function createToken(user) {
var token = jsonWebToken.sign({
id: user._id,
name: user.name,
username: user.username
}, sessionSecret, {expiresInMinutes: 1440});
return token;
}
module.exports = function(app, express) {
var api = express.Router();
api.post('/login', function(req,res) {
User.findOne({username: req.body.username})
.select('password').exec(function(err, user) {
if (err) {
res.send(err);
return;
} else {
if (!user) {
res.send('user does not exist!');
} else {
var isPasswordValid = user.comparePassword(req.body.password);
if (!isPasswordValid) {
res.send('wrong password!');
} else {
var token = createToken(user);
res.json(
{success:true,
message:'successfully logged in!',
token: token});
}
}
}
})
});
api.use(function(req,res,next) {
console.log('someone tried to access a secure page');
var token =
req.body.token || req.param('token') || req.headers['x-access-token'];
if (token) {
jsonWebToken.verify(token, sessionSecret, function(err, decoded) {
if(err) {
res.status(403).send({ success: false, message: "Failed to authenticate user"});
} else {
//
req.decoded = decoded;
next();
}
});
} else {
**//*****the message sent to my frontend*********
res.status(403).send({ success: false, message: "No Token Provided"});
}
});
api.get('/me', function(req,res) {
res.send(req.decoded);
})
app.use('/api', api);
}
frontend:
Angular factory: retrieves data from the backend
var authService = angular.module('authService', []);
authService.factory('Auth', function($http, $location, $q, AuthToken) {
var authFactory = {};
authFactory.login = function(username,password) {
return $http.post('/api/login', {
username: username,
password: password
}).success(function(data) {
AuthToken.setToken(data.token);
return data;
})
}
authFactory.getUser = function() {
if (AuthToken.getToken()) {
return $http.get('/api/me');
} else {
return $q.reject({message: 'unable to get data'});
}
}
return authFactory;
});
authService.factory('AuthToken', function($window) {
var authTokenFactory = {};
authTokenFactory.getToken = function() {
return $window.localStorage.getItem('token');
}
authTokenFactory.setToken = function(token) {
if (token) {
$window.localStorage.setItem('token', token);
} else {
$window.localStorage.removeItem('token');
}
}
return authTokenFactory;
});
authService.factory('AuthInterceptor', function($q, $location, AuthToken) {
var interceptorFactory = {};
interceptorFactory.request = function(config) {
var token = AuthToken.getToken();
if(token) {
config.headers['x-access-token'] = token;
}
return config;
};
interceptorFactory.responseError = function(response) {
if (response.status === 403) {
$location.path('/login');
return $q.reject(response);
}
}
});
mainController:
angular.module('MainController', [])
.controller('mainController', ['$rootScope','$location','Auth', function($rootScope,$location, Auth) {
var vm = this;
vm.isLoggedIn = Auth.isLogged();
$rootScope.$on('$routeChangeStart', function() {
vm.isLoggedIn = Auth.isLogged();
Auth.getUser().then(function(data) {
vm.user = data.data;
})
})
vm.login = function() {
vm.error = '';
Auth.login(vm.loginData.username, vm.loginData.password)
.then(function(data) {
Auth.getUser()
.then(function(data) {
vm.user = data.data;
});
if (data.success) {
$location.path('/');
} else {
vm.error = data.message;
console.log(vm.error);
}
});
}
index.html:
<!DOCTYPE html>
<html ng-app="myApp">
<base href="/">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://code.angularjs.org/1.4.0-rc.1/angular.min.js"></script>
<script src="https://code.angularjs.org/1.4.0-rc.1/angular-route.min.js"></script>
<!--angular services -->
<script src="app/auth/authService.js"></script>
<!--angular controllers -->
<script src="app/controllers/mainController.js"></script>
<script src="app/app.routes.js"></script>
<script src="app/app.js"></script>
</head>
<body>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
login.html:
<div class="container" ng-controller="mainController as login">
<form method="post" ng-submit="login.login()">
username: <input type="text" name="username" ng-model="login.loginData.username">
password: <input type="password" name="password" ng-model="login.loginData.password">
<button type="submit" class="btn btn-success">submit</button>
</form>
</div>
further code will be made available upon request. I will be truly grateful for any help as I have spent countless hours trying to solve this problem.

I guess the redirection is happening before the getting the data:
vm.login = function() {
vm.error = '';
Auth.login(vm.loginData.username, vm.loginData.password)
.then(function(resp) { // <------changed the arg to 'resp'
Auth.getUser()
.then(function(data) {
vm.user = data.data;
if (resp.success) { // <------put the condition here with 'resp'
$location.path('/');
} else {
vm.error = resp.message;
console.log(vm.error);
}
});
});
}
Another change i can suggest you to use .then() instead of .success() here:
return $http.post('/api/login', {
username: username,
password: password
}).then(function(data) { // <--------change to `.then()`
AuthToken.setToken(data.token);
return data;
})

Related

login authentication issue in angularjs

I have created login page and for accessing data I have used JSON File. when I click on the login() btn , userdata should match with the server data. But I am getting error and I am not able to send the $http response to the client side from server. If the rows with that name and password matches it return true, if not return false. then the client should parse this response.
But I don't know how What I am doing wrong?
Any help / advice would be greatly appreciated.
AngualJS:
/* server-side */
app.factory('auth', function ($http, session) {
var authService = {};
authService.login = function (username, password) {
var response;
$http.post('http://localhost:3000/loginfo')
.then(
function successCallback(response) {
var user = response.data;
console.log(user);
if (user.username == username && user.password == password) {
var signinfo = response.data;
console.log(response.data);
} else {
console.log('Error');
}
})
};
authService.isAuthenticated = function () {
return {
isAuthenticated: false,
user: null
}
};
return authService;
});
/* client-side */
app.controller('credientials', function ($scope, $http, auth) {
$scope.userCred = {
username: '',
password: ''
};
/*-----Form Submition-----*/
$scope.log = function (userCred) {
auth.isAuthenticated = true;
auth.login(userCred.username, userCred.password, function (response) {
if (response.success) {
console.log('success');
} else {
console.log('Error');
}
})
};
});

unsupported_grant_type error in angularJS and web API

I am trying to achieve user login
and logout using angularJS and web Api
But the server always return badrequest (400)
exception
the error is coming from this bit of code
AuthApp.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
var authServiceFactory = {};
var _authentication =
{
isAuth: false,
userName: ""
};
// this is the login function
authServiceFactory.login = function (loginData)
{
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password; //is not working
//var data = { username: loginData.userName, password: loginData.password, grant_type: "password" }; // I try this and is not working too
//data = $.param(data);
// how should I format my data for the web API to understand
var deferred = $q.defer();
// alert(data);
$http.post('/token', data, {
header: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function (response) {
localStorageService.set('authorizationData', { token: response.access_token, userName: response.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
deferred.resolve(response);
}).error(function (err) {
// _logout();
deferred.reject(err);
});
return deferred.promise;
}
authServiceFactory.logout = function ()
{
localStorageService.remove("authenticationData");
_authentication.isAuth = false;
_authentication.userName = "";
}
return authServiceFactory;
}]);
using postman to further see the error
this appears
{ "error": "unsupported_grant_type" }
I made google search but still no solution; how can I resolve this issue?
thanks in advance!!

what is "error": "unsupported_grant_type" in web Api

I am trying to achieve user login
and logout using angularJS and web Api
But the server always return badrequest (400)
exception
the error is coming from this bit of code
AuthApp.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
var authServiceFactory = {};
var _authentication =
{
isAuth: false,
userName: ""
};
// this is the login function
authServiceFactory.login = function (loginData) {
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
var deferred = $q.defer();
// alert(data);
$http.post('/token', data, {
header: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function (response) {
localStorageService.set('authorizationData', { token: response.access_token, userName: response.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
deferred.resolve(response);
}).error(function (err) {
// _logout();
deferred.reject(err);
});
return deferred.promise;
}
authServiceFactory.logout = function ()
{
localStorageService.remove("authenticationData");
_authentication.isAuth = false;
_authentication.userName = "";
}
return authServiceFactory;
}]);
using postman to further see the error
this appears
{ "error": "unsupported_grant_type" }

$window.sessionStorage for login and logout ( token based);

I create a login and logout function with Node.js and Angular.js which is token based. The token I am saving into window storage.
The problem is if I logout it just logout for one browser and also if I loggedin it not recognize if I am already loggedin. I think I have to extend my programm.
My question is how can I delete the storage for every open browser where I loggedin? Or schould I ask within my code if I am loggedin and how could I do this?
Thanks in advance!
NODE.JS CODE
app.post('/logout', function(req, res){
jwt.verify(req.body.token, 'secretKey', function(err, decoded) {
console.log("Decoded " + decoded);
if(decoded._id != null){
User.findOne({
_id : decoded._id
}, function(err, user) {
if (err) {
console.log('Error occured', err);
} else {
if (user) {
res.end();
}
}
});
}else{
Console.log("Could not logout");
}
});
});
app.post('/login', function(req, res) {
User.findOne({
email : req.body.email
}, function(err, user) {
if (err) {
console.log('Error occured', err);
} else {
if (user) {
// check if password matches
if (req.body.password != undefined) {
var hashPWCheck = bcrypt.compareSync(req.body.password, user.password);
// true
//console.log(hashPWCheck);
if (!(hashPWCheck)) {
res.json({
success : false,
message : 'Authentication failed. Wrong password.'
});
console.log('Authentication failed. Wrong password.');
} else {
var token = jwt.sign(user, 'secretKey', {
expiresInMinutes : 60 // expires in 1 Minute
});
res.json({token : token, email : user.email});
console.log("Token created & sent to Client(UserCtrlLogin): " + token);
}
} else {
console.log("Password is required!");
}
} else {
console.log("Incorect E-Mail");
}
}
});
});
ANGULAR.js Code
app.controller('UserCtrlLogin', function($scope, $http, $window, $location, $rootScope) {
$scope.logout = function(){
var sessionlogout = $window.sessionStorage.getItem('token');
var formData = {
token : sessionlogout
};
$http.post('/logout', formData).success(function(data, status, headers, config) {
if(status == 200){
$rootScope.isAlive = false;
$rootScope.ali = false;
$window.sessionStorage.removeItem('token');
}else{
$window.sessionStorage.removeItem('token');
$rootScope.isAlive = false;
}
});
};
$scope.signin = function() {
var formData = {
email : $scope.email,
password : $scope.password
};
// $window.sessionStorage.removeItem('token');
$http.post('/login', formData).success(function(data, status, headers, config) {
console.log('Data: ' + data.email);
//console.log('Status: ' + status);
if (status == 200) {
if(data.email == "goekguel.ali#gmail.com"){
$rootScope.ali = true;
}
$rootScope.isAlive = true;
$window.sessionStorage.setItem('token', data.token);
console.log("Token saved into Storage from Server(Node.js function /login)");
}
}).error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
$window.sessionStorage.removeItem('token');
});
};
});
You need to save tokens in the database, and if you log in or log out in one browser you have to mark token as valid/invalid, and in another browser it's required to check token status on backend.
P.s. See satellizer, it's just my recommendation for front-end auth module.

Token is not defined - MEAN Stack

I've been following a book tutorial called mean machine. It has been super helpful. I am setting up authentication and can't figure out this error I'm getting.
Any help would be greatly appreciated! I can't seem to find the answer anywhere else.
ERROR: token is not defined
at Object.authTokenFactory.setToken (authService.js:69)
authService.js:
angular.module('authService', [])
// ===================================================
// auth factory to login and get information
// inject $http for communicating with the API
// inject $q to return promise objects
// inject AuthToken to manage tokens
// ===================================================
.factory('Auth', function($http, $q, AuthToken) {
// create auth factory obj
var authFactory = {};
// login user
authFactory.login = function(username, password) {
// return promise obj and its data
return $http.post('/api/authenticate', {
username: username,
password: password
})
.success(function(data) {
AuthToken.setToken(data.token);
return data;
});
};
// logout user by clearing token
authFactory.logout = function() {
AuthToken.setToken();
};
// check if user is logged in
// checks for local token
authFactory.isLoggedIn = function() {
if (AuthToken.getToken())
return true;
else
return false;
};
// get logged in user
authFactory.getUser = function() {
if (AuthToken.getToken())
return $http.get('/api/me', { cache : true});
else
return $q.reject({ message : 'User has no token.'});
};
return authFactory;
})
// ===================================================
// factory for handling tokens
// inject $window to store token client-side
//
//
// ===================================================
.factory('AuthToken', function($window) {
var authTokenFactory = {};
// get token out of local storage
authTokenFactory.getToken = function() {
return $window.localStorage.getItem('token');
};
// function to set token or clear token
// if a token is passed, set the token
// if there is no token, clear it from local storage
authTokenFactory.setToken = function() {
if (token)
$window.localStorage.setItem('token', token);
else
$window.localStorage.removeItem('token');
};
return authTokenFactory;
})
// ===================================================
// application configuration to integrate token into requests
// ===================================================
.factory('AuthInterceptor', function($q, $location, AuthToken) {
var interceptorFactory = {};
// this will happen on all http requests
interceptorFactory.request = function(config) {
// grab token
var token = AuthToken.getToken;
// if token exists add it to the header as x-access-token
if (token)
config.headers['x-access-token'] = token;
return config;
};
// happens on response errors
interceptorFactory.responseError = function(response) {
// if 403 from server
if (response.status == 403) {
AuthToken.setToken();
$location.path('/login')
}
//return the errors from server as promise
return $q.reject(response);
};
return interceptorFactory;
});
mainCtrl.js
angular.module('mainCtrl', [])
.controller('MainController', function($rootScope, $location, Auth) {
var vm = this;
// get info if a person is logged in
vm.loggedIn = Auth.isLoggedIn();
// check to see if user is logged in on every req
$rootScope.$on('$routeChangeStart', function() {
vm.loggedIn = Auth.isLoggedIn();
// get user info on route change
// Auth.getUser()
// .success(function(data) {
// vm.u = data;
// });
Auth.getUser().then(function (data) {
vm.user = data;
},
function (response) {
// Handle case where user is not logged in
// or http request fails
});
});
// handle login form
vm.doLogin = function () {
vm.processing = true;
// clear error
vm.error = '';
// call Auth.login() func
Auth.login(vm.loginData.username, vm.loginData.password)
.success(function(data) {
vm.processing = false;
//if a user logs in, redirect to users pg
if (data.success)
$location.path('/users');
else
vm.error = data.message;
});
};
// log out
vm.doLogOut = function() {
Auth.logout();
vm.u = {};
$location.path('/login');
};
});
The error message you've received really says it all. The token variable is never defined in authTokenFactory.setToken().
authTokenFactory.setToken = function(token) { // Add this variable delcaration
if (token)
$window.localStorage.setItem('token', token);
else
$window.localStorage.removeItem('token');
};
}

Categories

Resources