当我在表单上单击注册时,从我可以理解的角度来看,在节点服务器可以授权JWT并发送200 OK之前,将URL设置为/ profile(受保护的路由)。我不确定如何防止这种情况。
即使我在本地存储中有令牌,受保护的路由也会返回并且是未经授权的错误。因此,即使发送了200 OK响应,如果我重新加载/ profile路由,它仍将获得401.
路线:
const path = require('path');
const Company = require('./models/app');
const User = require('./models/users');
const jwt = require('express-jwt');
let auth = jwt({
secret: process.env.CONFIG_SR,
requestProperty: 'payload'
});
module.exports = function(app , passport) {
function profileCheck(req , res , next) {
if(!req.payload._id) {
res.status(401).json({
"message" : "UnauthorizedError: private profile"
});
} else {
User.findById(req.payload._id)
.exec(function(err, user) {
res.status(200).json(user);
});
}
}
app.get('/' , function(req , res) {
res.sendFile(path.join(__dirname , '../public' , 'index.html'));
});
app.get('/login' , function(req , res) {
res.sendFile(path.join(__dirname , '../public' , 'login.html'));
});
app.post('/api/login' , function(req, res) {
passport.authenticate('local' , function(err, user, info) {
if(err) {
return res.json({
'message': err
});
} if(user) {
token = user.generateJwt();
res.status(200);
res.json({
"token" : token
});
} else {
return res.json({
'message': 'User not found'
});
}
})(req, res);
});
app.get('/register' , function(req , res) {
res.sendFile(path.join(__dirname , '../public' , 'register.html'));
});
app.post('/api/register' , function(req, res) {
User.findOne({'local.email': req.body.email}, function(err, user) {
if(err) {
return res.json({
'message': err
});
}
if(user) {
return res.json({
'message': 'User already exists'
});
} else {
let newUser = new User();
newUser.local.email = req.body.email;
newUser.local.name = req.body.name;
newUser.local.password = newUser.setPassword(req.body.password);
newUser.save(function(err) {
// passport.authenticate('local',{ session: false }, function(req, res) {});
var token;
token = newUser.generateJwt();
res.status(200);
res.json({
'token': token
});
});
}
});
});
app.get('/profile', auth, profileCheck, function(req , res) {
res.render('profile.jade');
});
app.get('/logout' , function(req , res) {
req.logout();
res.json({
'message': 'Bye'
});
});
}
控制器
app.controller('authController', ['$scope', '$http', '$window', 'authenticationService', 'restrictData', function($scope, $http, $window, authenticationService, restrictData) {
$scope.credentials = {
name : "",
email : "",
password : ""
}
$scope.user = {};
$scope.regSubmit = function() {
authenticationService.register($scope.credentials)
.error(function(err) {
console.log(err);
}).then(function() {
restrictData.getProfile()
.success(function(data) {
$scope.user = data;
}).error(function(e) {
console.log(e);
});
var url = '/profile';
$window.location.href = url;
});
}
$scope.logSubmit = function() {
authenticationService.login($scope.credentials)
.error(function(err) {
console.log(err);
}).then(function() {
var url = '/profile';
$window.location.href = url;
});
}
$scope.isLoggedIn = authenticationService.isLoggedIn();
$scope.currentUser = authenticationService.currentUser();
}]);
服务1:
app.factory('authenticationService',['$http', '$window', '$timeout', '$q' , function($http, $window, $timeout, $q) {
var saveToken = function(token){
$window.localStorage['mean-token'] = token;
}
var getToken = function(){
return $window.localStorage['mean-token'];
}
var logout = function(){
$window.localStorage.removeItem('mean-token');
}
var isLoggedIn = function() {
var token = getToken();
var payload;
if(token) {
payload = token.split('.')[1];
payload = $window.atob(payload);
payload = JSON.parse(payload);
return payload.exp > Date.now() / 1000;
} else {
return false;
}
}
var currentUser = function() {
if(isLoggedIn()) {
var token = getToken();
var payload = token.split('.')[1];
payload = $window.atob(payload);
payload = JSON.parse(payload);
return {
email : payload.email,
name : payload.name
};
}
}
register = function(user) {
return $http.post('/api/register', user).success(function(data){
saveToken(data.token);
});
};
login = function(user) {
return $http.post('/api/login', user).success(function(data) {
saveToken(data.token);
});
};
return {
saveToken: saveToken,
getToken: getToken,
isLoggedIn: isLoggedIn,
currentUser: currentUser,
register: register,
login: login,
logout: logout
};
}]);
服务2:
app.factory('restrictData', function($http, authenticationService) {
var getProfile = function() {
return $http.get('/profile', {
headers: {
Authorization: 'Bearer ' + authenticationService.getToken()
}
});
}
return {
getProfile: getProfile
}
});
答案 0 :(得分:0)
因此,根据我在研究中发现的情况,使用JWT保护非api路线是不明智或不可行的。因此,为了使我的应用程序正常工作,我将前端页面的所有路由转移到角度侧。它并不是特别想要,但它最终正在努力解决这个问题。
我删除了所有导致前端页面的get请求,如下所示:
app.get('/' , function(req , res) {
res.sendFile(path.join(__dirname , '../public' , 'index.html'));
});
然后我使用routeProvider(确保在页面上包含angular-route以便这样做)来路由所有路径:
app.config(function($routeProvider , $locationProvider) {
$routeProvider
.when('/', {
templateUrl: './ui/home.html',
}).when('/compare', {
templateUrl: './ui/compare.html',
}).when('/contact', {
templateUrl: './ui/contact.html',
}).when('/login', {
templateUrl: './ui/login.html',
}).when('/register', {
templateUrl: './ui/register.html',
}).when('/profile', {
templateUrl: './ui/profile.html',
});
$locationProvider.html5Mode(true);
});
app.run(function($rootScope, $location, authenticationService) {
$rootScope.$on('$routeChangeStart', function(event, nextRoute, currentRoute) {
if ($location.path() === '/profile' && !authenticationService.isLoggedIn()) {
$location.path('/');
}
});
});
然后相应地调整了其余的代码