Перенаправление страницы с угловой маршрутизацией после успешного вызова API на экспресс-сервере
В одностраничном приложении, использующем угловую маршрутизацию, как я могу перенаправить страницу после вызова API. В моем случае я хочу перенаправить пользователя на страницу профиля после того, как он вызвал API входа в систему. Так что я думал, что это сработает, но это не так.
На клиенте main.js. У меня настроена угловая маршрутизация
app.config(function($routeProvider){ $routeProvider
//the home page display
.when('/', {
templateUrl: 'main.html',
controller: 'mainController'
})
.when('/login', {
templateUrl: 'login.html',
controller: 'loginController'
})
.when('/signUp', {
templateUrl: 'signUp.html',
controller: 'signUpController'
})
.when('/profile', {
templateUrl: 'profile.html',
//controller: 'mainController'
}); });
и с моего контроллера я вызываю / логин пост API
app.controller('authController', function($scope, $http, $rootScope, $location){
$scope.user = {username: '', password: ''};
$scope.error_message = '';
$scope.login = function(){
$http.post('/login', $scope.user).success(function(data){
if(data.state == 'success'){
//set username authenticated property to true after successful log in
//I am only pasting some of my code here, more logic before controller
$rootScope.authenticated = true;
$rootScope.current_user = "james";
$location.path('/profile');
}
else{
$scope.error_message = data.message;
}
});
};
});
и вот мой логин API
router.post('/login', passport.authenticate('local-login', {
successRedirect : '/success', // redirect to the secure profile section
failureRedirect : '/failure', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
и когда это успешно, это вызывает успех, который возвращает данные, которые должны вызвать обратный вызов в $http.post и перенаправить страницу через $location.path('/profile');. Однако обратный вызов не вызывается, и на моей странице отображается информация о пользователе из res.send.
//sends successful login state back to angular
router.get('/success', function(req, res){
res.send({state: 'success', user: req.user ? req.user : null});
});
Я на правильном пути? Я просто следую учебному пособию Майкрософт https://www.microsoftvirtualacademy.com/en-us/training-courses/mean-stack-jump-start-8442 но их заполненная страница на github даже не работает, поэтому не помогает я отлаживаю эту мою проблему.
3 ответа
С помощью successRedirect
а также failureRedirect
в паспорте перенаправит клиента на указанные страницы, что предотвратит вашу маршрутизацию angularJS на стороне клиента. Причина, по которой вы видите информацию о пользователе после входа в систему, заключается в том, что ваш клиент перенаправляется на /success
страницы, а не фактически отвечая на первоначальный запрос. Затем клиент извлекает страницу успеха с помощью запроса GET, и на новый запрос GET затем отправляется информация о пользователе.
Я бы предложил оставить перенаправления node.js при использовании AngularJS, так как вы, вероятно, захотите обработать перенаправление на стороне клиента:
router.post('/login', passport.authenticate('local-login'), function(req, res){
res.send(req.user);
});
Встроенная функция никогда не будет выполняться, если пользователь не аутентифицирован. Вместо этого, паспорт ответит напрямую с ошибкой 401, с телом "Unauthorized". Следовательно success
состояние не требуется. На стороне клиента вы должны использовать .error()
функция для устранения ошибок 401 вместо проверки вашей переменной состояния:
$http.post('/login', $scope.user).success(function(user){
$rootScope.authenticated = true;
$rootScope.current_user = "james";
$location.path('/profile');
})
.error(function(err){
$scope.error_message = err;
});
Если вы хотите передать более конкретную причину того, почему запрос был неавторизованным (что не всегда является хорошей идеей), вы можете использовать флэш-сообщения и выполнить другой запрос GET от angular, чтобы получить более подробное сообщение об ошибке авторизации.
Похоже, у вас небольшое несоответствие импеданса в том, что интерфейс и сервер хотят здесь сделать. В вашем коде AngularJS предполагается сделать POST для конечной точки API и получить 200 (успех) вместе с некоторыми данными JSON, которые сообщают ему об успехе или неудаче попытки входа в систему.
Серверная часть думает, что получит POST, а затем перенаправит абонента в новое место. По крайней мере, так я это читаю. Это не просто отправка некоторых данных с HTTP-кодом ответа 200 или кодом ошибки.
Я думаю, что вы хотите настроить внутренний код, чтобы просто возвращать данные во внешний интерфейс, чтобы получить ожидаемый результат.
До сих пор я не видел успеха в том, чтобы Ajax обращался к API, перенаправляя на страницу. У нас похожая ситуация, когда вызов API может привести к перенаправлению на страницу ошибки. Мы хотели обработать это на сервере, а не запрашивать пользовательский интерфейс (Angular). Но просто печально видеть, что ни один из методов перенаправления, таких как res.redirect, не работает. Наш сценарий заключается в том, что Angular делает вызов API через Ajax, и API, работающий на Node.js, должен перенаправлять на html-страницу.