javascript - validar formulario angular 5
AngularJS: verifica si un usuario está autenticado y luego los enruta a la página correcta (9)
En authInterceptor agregar código para la respuesta. Asi que:
return {
request: function(config) {
if(config.url.indexOf(API) === 0) {
request.headers = request.headers || {};
request.headers[''X-PCC-API-TOKEN''] = localStorage.getItem(''token'');
}
return config;
},
response: function(response) {
//ok response - code 200
return response;
},
responseError: function(response){
//wrong response - different response code
}
};
En el lado del servidor, verifique el encabezado http X-PCC-API-TOKEN y si la respuesta es incorrecta (sin autenticación) debe tener un código diferente, como el 403. Por lo tanto, el método responseError se ejecutará en el interceptor.
responseError: function(response){
//wrong response - different response code
if (response.status === 403) {
alert("No rights to page");//your code for no auth
//redirect to different route
$injector.get(''$state'').transitionTo(''login'');//use injector service
return $q.reject(response);//return rejection - use $q
}
}
Lo que estoy buscando hacer cuando un usuario llega a la página index.html necesito el módulo de inicio de sesión para hacer 2 cosas:
Necesito esto para verificar si un usuario está autenticado (lo cual creo que ya empecé con la "función authService") si el usuario tiene un token válido, luego cambie la vista ui a dashboard / dashboard.html y si la clave no es válida o no hay ninguna clave, luego cargue login / login.html en ui-view.
Una vez que hayan iniciado sesión correctamente, quiero que se dirijan a "dashboard / dashboard.html"
Aquí está mi script de inicio de sesión:
function authInterceptor(API) {
return {
request: function(config) {
if(config.url.indexOf(API) === 0) {
request.headers = request.headers || {};
request.headers[''X-PCC-API-TOKEN''] = localStorage.getItem(''token'');
}
return config;
}
}
}
function authService(auth) {
var self = this;
self.isAuthed = function() {
localStorage.getItem(''token'');
}
}
function userService($http, API) {
$http.defaults.headers.post[''Content-Type''] = ''application/x-www-form-urlencoded;'';
$http.defaults.transformRequest = [function(data) {
return angular.isObject(data) && String(data) !== ''[object File]'' ? param(data) : data;
}];
var self = this;
self.login = function(username, pwd, ctrl) {
ctrl.requestdata = API + ''/winauth'' + ''; with '' + username;
return $http.post(API + ''/winauth'', {
username: username,
pwd: pwd
})
};
var param = function(obj) {
var query = '''', name, value, fullSubName, subName, subValue, innerObj, i;
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
for(i=0; i<value.length; ++i) {
subValue = value[i];
fullSubName = name + ''['' + i + '']'';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + ''&'';
}
}
else if(value instanceof Object) {
for(subName in value) {
subValue = value[subName];
fullSubName = name + ''['' + subName + '']'';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + ''&'';
}
}
else if(value !== undefined && value !== null)
query += encodeURIComponent(name) + ''='' + encodeURIComponent(value) + ''&'';
}
return query.length ? query.substr(0, query.length - 1) : query;
};
}
function LoginCtrl(user) {
var self = this;
function handleRequest(res) {
self.responsedata = res;
self.message = res.data.message;
var authToken = res.data.auth_token;
localStorage.setItem(''token'', authToken);
}
self.login = function() {
this.requestdata = ''Starting request...'';
user.login(self.username, self.pwd, self)
.then(handleRequest, handleRequest)
}
}
// Login Module
var login = angular.module(''login'', ["ui.router"])
login.factory(''authInterceptor'', authInterceptor)
login.service(''user'', userService)
login.service(''auth'', authService)
login.constant(''API'', ''http://myserver.com/api'')
EDITAR: agregué esto a mi controlador de inicio de sesión para proporcionar las rutas de inicio de sesión
login.config(function($httpProvider, $stateProvider, $urlRouterProvider) {
$httpProvider.interceptors.push(''authInterceptor'');
$urlRouterProvider.otherwise(''/login'');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state(''login'', {
url: ''/login'',
templateUrl: ''login/login.html'',
controller: "mainLogin",
controllerAs: "log"
})
// nested list with just some random string data
.state(''dashboard'', {
url: ''/dashboard'',
templateUrl: ''dashboard/dashboard.html'',
})
})
login.controller(''mainLogin'', LoginCtrl)
Aquí está mi index.html:
EDITAR - Eliminé "ng-include" y agregué "ng-view" para controlar las rutas.
<body ng-app="login" ng-controller="mainLogin as log" class="loginPage">
<div class="main" ui-view></div>
</body>
Como puede ver, tengo una función que está comprobando el token en el almacenamiento local de los usuarios:
function authService(auth) {
var self = this;
self.isAuthed = function() {
localStorage.getItem(''token'');
}
}
Y lo estoy cargando en el módulo como servicio:
login.service(''auth'', authService)
Aquí es donde estoy atrapado. No sé a dónde ir desde aquí. Ni siquiera sé si estoy usando mi función authService correctamente. Todavía estoy aprendiendo mucho sobre AngularJS, por lo que es fácil para mí quedarme atascado. :)
Otra cosa que notará es en mi archivo index.html. Estoy cargando el parcial "login / login.html" como predeterminado. Lo necesito para cargar login.html o dashboard.html dependiendo de si han iniciado sesión o no. Y luego enróllelas a dashboard.html una vez que hayan iniciado sesión correctamente.
La secuencia de comandos funciona muy bien hasta que llega a la API de autenticación, autentica al usuario y luego almacena una clave de autenticación válida en su almacenamiento local.
Alguien sabe como puedo lograr esto?
Hay dos preocupaciones separadas con las que está tratando. La primera, es poder determinar si está conectado. Suponiendo que el usuario debe iniciar sesión en cualquier estado excepto en el estado de inicio de sesión, lo implementaría así escuchando los eventos de $ stateChangeState y verificando que el usuario haya iniciado sesión. en:
login.run(function($state, authService) {
$rootScope.$on(''$stateChangeStart'', function (event, toState, toParams, fromState, fromParams) {
var authToken = authService.isAuthed();
if (!authToken && toState !== ''login'') {
//not logged in, so redirect to the login view instead of the view
//the user was attempting to load
event.preventDefault();
$state.go(''login'');
}
})
});
Esto los pondrá en el estado de inicio de sesión si aún no han iniciado sesión.
La segunda parte es redirigir a la vista correcta después de iniciar sesión, lo que haría en su controlador de inicio de sesión:
function LoginCtrl(user, $state) {
var self = this;
function handleRequest(res) {
self.responsedata = res;
self.message = res.data.message;
var authToken = res.data.auth_token;
localStorage.setItem(''token'', authToken);
//after successful login, redirect to dashboard
$state.go(''dashboard'');
}
self.login = function() {
this.requestdata = ''Starting request...'';
user.login(self.username, self.pwd, self)
.then(handleRequest, handleRequest)
}
}
Hay una forma sencilla de lograr lo que quiere para su aplicación, utilizando Passport .
La documentación es bastante simple y fácil de implementar.
También puede consultar este tutorial para implementar la autenticación mediante Passport. Este tutorial enseña de una manera muy simple, cómo hacer la autenticación para su aplicación.
Su código no está verificando los cambios de URL ni afectando las rutas de manera transversal.
Recuerde que la autenticación y la autorización son preocupaciones transversales. Dicho esto, Angular tiene una forma de interceptar llamadas de enrutamiento escuchando en $ routeChangeStart. Su "interceptor" se debe agregar allí. A continuación, puede redireccionar el enrutador a la vista requerida enrutando manualmente allí. Echar un vistazo como la solución de un hilo de desbordamiento de pila anterior .
Su servicio está bien y está en el módulo de inicio de sesión, pero no lo está utilizando en ningún lugar donde pueda verlo. Necesitas inyectar tu servicio en el controlador para hacer las cosas que quieres. En su servicio de autenticación, obtiene un artículo de localstorage pero no está devolviendo nada, por ejemplo, tiene su servicio de inicio de sesión
function authService(auth) {
var self = this;
self.isAuthed = function() {
return localStorage.getItem(''token'');
}
}
//here you can inject your auth service to get it work as you want
function LoginCtrl(user, auth) {
var self = this;
function handleRequest(res) {
self.responsedata = res;
self.message = res.data.message;
var authToken = res.data.auth_token;
localStorage.setItem(''token'', authToken);
}
self.login = function() {
this.requestdata = ''Starting request...'';
user.login(self.username, self.pwd, self)
.then(handleRequest, handleRequest)
}
}
login.service(''auth'', authService)
Una forma sencilla de hacerlo es usar el paquete https://github.com/Emallates/ng-enoa-auth . Solo necesitas incluirlo en tu aplicación, nada más.
Usted manejaría la lógica dentro de su controlador de inicio de sesión específicamente aquí:
self.login = function() {
this.requestdata = ''Starting request...'';
user.login(self.username, self.pwd, self)
.then(handleRequest, handleRequest)
}
Dentro de la devolución de llamada para el éxito en el inicio de sesión, simplemente haría un cambio de estado para enviar al usuario al estado correcto.
ok, veo que estás usando ui.router así que trabajemos dentro de este marco.
Tú quieres
- verifica si un usuario ha iniciado sesión
- redirigir al usuario a una vista
Lo que estás buscando es resolve:{loggedIn: checkLoggedInFn}
por lo que su ruta para el tablero de mandos podría ser algo así como
.state(''dashboard'', {
url: ''/dashboard'',
templateUrl: ''dashboard/dashboard.html'',
resolve: {
loggedIn: function(){
//do your checking here
}
}
})
básicamente, lo que esto hace es que el controlador no creará una instancia hasta que se resuelva cada resolución (por lo que puede usar una promesa aquí, por ejemplo), y luego el valor se pasa al controlador como un parámetro, por lo que podría hacer algo como:
if(!loggedIn){
$state.go(''login'');
}
function authService(auth) {
var self = this;
self.isAuthed = function() {
**localStorage.getItem(''token'');**
}
}
¿Dónde estás metiendo el elemento localstorage ? Falta el valor de LValue.
En el nivel más básico, puede manejar una comprobación de este elemento (token) en la página Panel de instrumentos, al momento de cargar la página y, si es nulo, es decir. vacío, luego redirigir / enrutar al usuario a la página de inicio de sesión. Por cierto, use sessionStorage en lugar de localStorage ya que el primero se vaciará tan pronto como se cierre la sesión del navegador.
Hay formas más elegantes y sencillas de lograrlo como Passport . ¿Lo has comprobado? Es tan simple como esto:
app.post(''/login'', passport.authenticate(''local'', { successRedirect: ''/'',
failureRedirect:''/login''}));