javascript - proyecto - rutas angularjs
AngularJS: ejemplo básico para usar la autenticación en la aplicación de una sola página (6)
Soy nuevo en AngularJS y pasé por su tutorial y lo sentí.
Tengo un back-end para mi proyecto listo donde cada uno de los puntos finales REST
necesita ser autenticado.
Lo que quiero hacer
a.) Quiero tener una sola página para mi proyecto http://myproject.com
.
b.) Una vez que un usuario acierta la URL en el navegador, en función de si el usuario está conectado o no, se le presenta una página de inicio / vista o página de inicio / vista bajo la misma URL http://myproject.com
.
c.) si un usuario no ha iniciado sesión, rellena el formulario y el servidor establece un USER_TOKEN
en sesión, por lo que todas las demás solicitudes a los puntos finales se autenticarán en función de USER_TOKEN
Mis Confusiones
a.) ¿Cómo puedo manejar la autenticación del lado del cliente usando AngularJS? Vi here y here pero no entendí cómo usarlos
b.) ¿Cómo puedo presentar diferentes vistas al usuario en función de si el usuario está conectado o no en la misma url http://myproject.com
Estoy usando angular.js por primera vez y realmente estoy confundido sobre cómo comenzar. Cualquier consejo y / o recurso es muy apreciado.
Creo que cada respuesta JSON debe contener una propiedad (por ejemplo, {authenticated: false}) y el cliente debe probarla siempre: si es falsa, el controlador / servicio angular se "redireccionará" a la página de inicio de sesión.
¿Y qué pasa si el usuario atrapa de JSON y cambia el bool a True?
Creo que nunca deberías confiar en el lado del cliente para hacer este tipo de cosas. Si el usuario no está autenticado, el servidor simplemente debe redirigir a una página de inicio de sesión / error.
En angularjs puede crear la parte UI, el servicio, las directivas y toda la parte de angularjs que representa la interfaz de usuario. Es una buena tecnología para trabajar.
Como cualquiera que sea nuevo en esta tecnología y desee autenticar al "Usuario", le sugiero que lo haga con el poder de c # web api. para eso puedes usar la especificación OAuth que te ayudará a construir un fuerte mecanismo de seguridad para autenticar al usuario. una vez que construyes el WebApi con OAuth necesitas llamar a esa API para token:
var _login = function (loginData) {
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
var deferred = $q.defer();
$http.post(serviceBase + ''token'', data, { headers: { ''Content-Type'': ''application/x-www-form-urlencoded'' } }).success(function (response) {
localStorageService.set(''authorizationData'', { token: response.access_token, userName: loginData.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};
y una vez que obtienes el token, solicitas los recursos de angularjs con la ayuda de Token y tienes acceso al recurso que se mantiene seguro en la API web con especificación OAuth.
Eche un vistazo al siguiente artículo para obtener más ayuda:
He creado un repositorio github resumiendo este artículo básicamente: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
Trataré de explicar lo mejor posible, espero ayudar a algunos de ustedes:
(1) app.js: creación de constantes de autenticación en la definición de la aplicación
var loginApp = angular.module(''loginApp'', [''ui.router'', ''ui.bootstrap''])
/*Constants regarding user login defined here*/
.constant(''USER_ROLES'', {
all : ''*'',
admin : ''admin'',
editor : ''editor'',
guest : ''guest''
}).constant(''AUTH_EVENTS'', {
loginSuccess : ''auth-login-success'',
loginFailed : ''auth-login-failed'',
logoutSuccess : ''auth-logout-success'',
sessionTimeout : ''auth-session-timeout'',
notAuthenticated : ''auth-not-authenticated'',
notAuthorized : ''auth-not-authorized''
})
(2) Servicio de autenticación: todas las siguientes funciones se implementan en el servicio auth.js. El servicio $ http se usa para comunicarse con el servidor para los procedimientos de autenticación. También contiene funciones de autorización, es decir, si el usuario puede realizar una determinada acción.
angular.module(''loginApp'')
.factory(''Auth'', [ ''$http'', ''$rootScope'', ''$window'', ''Session'', ''AUTH_EVENTS'',
function($http, $rootScope, $window, Session, AUTH_EVENTS) {
authService.login() = [...]
authService.isAuthenticated() = [...]
authService.isAuthorized() = [...]
authService.logout() = [...]
return authService;
} ]);
(3) Sesión: Un singleton para guardar los datos del usuario. La implementación aquí depende de ti.
angular.module(''loginApp'').service(''Session'', function($rootScope, USER_ROLES) {
this.create = function(user) {
this.user = user;
this.userRole = user.userRole;
};
this.destroy = function() {
this.user = null;
this.userRole = null;
};
return this;
});
(4) Controlador principal: considere esto como la función "principal" de su aplicación, todos los controladores heredan de este controlador, y es la columna vertebral de la autenticación de esta aplicación.
<body ng-controller="ParentController">
[...]
</body>
(5) Control de acceso: para denegar el acceso en ciertas rutas, se deben implementar 2 pasos:
a) Agregue datos de las funciones permitidas para acceder a cada ruta, en el servicio $ stateProvider del enrutador ui, como se puede ver a continuación (lo mismo puede funcionar para ngRoute).
.config(function ($stateProvider, USER_ROLES) {
$stateProvider.state(''dashboard'', {
url: ''/dashboard'',
templateUrl: ''dashboard/index.html'',
data: {
authorizedRoles: [USER_ROLES.admin, USER_ROLES.editor]
}
});
})
b) En $ rootScope. $ on (''$ stateChangeStart'') agregue la función para evitar el cambio de estado si el usuario no está autorizado.
$rootScope.$on(''$stateChangeStart'', function (event, next) {
var authorizedRoles = next.data.authorizedRoles;
if (!Auth.isAuthorized(authorizedRoles)) {
event.preventDefault();
if (Auth.isAuthenticated()) {
// user is not allowed
$rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
} else {
// user is not logged in
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
}
});
(6) Interceptor de autenticación: esto se implementa, pero no se puede verificar en el alcance de este código. Después de cada solicitud $ http, este interceptor verifica el código de estado, si se devuelve uno de los siguientes, luego transmite un evento para obligar al usuario a iniciar sesión de nuevo.
angular.module(''loginApp'')
.factory(''AuthInterceptor'', [ ''$rootScope'', ''$q'', ''Session'', ''AUTH_EVENTS'',
function($rootScope, $q, Session, AUTH_EVENTS) {
return {
responseError : function(response) {
$rootScope.$broadcast({
401 : AUTH_EVENTS.notAuthenticated,
403 : AUTH_EVENTS.notAuthorized,
419 : AUTH_EVENTS.sessionTimeout,
440 : AUTH_EVENTS.sessionTimeout
}[response.status], response);
return $q.reject(response);
}
};
} ]);
PS Se puede evitar fácilmente un error con el autocompletado de datos de formulario como se indica en el primer artículo al agregar la directiva que se incluye en directives.js.
PS2 Este código puede ser ajustado fácilmente por el usuario, para permitir que se vean diferentes rutas, o para mostrar contenido que no debe mostrarse. La lógica DEBE implementarse desde el servidor, esta es solo una forma de mostrar las cosas correctamente en su aplicación ng.
Me gusta el enfoque y lo implementé en el lado del servidor sin hacer nada relacionado con la autenticación en el front-end
Mi ''técnica'' en mi última aplicación es ... al cliente no le importa Auth. Cada cosa en la aplicación requiere primero un inicio de sesión, por lo que el servidor siempre sirve una página de inicio de sesión a menos que se detecte un usuario existente en la sesión. Si se encuentra session.user, el servidor simplemente envía index.html. Bam: -o
Busque el comentario de "Andrew Joslin".
Respondí una pregunta similar aquí: AngularJS Authentication + RESTful API
He escrito un módulo AngularJS para UserApp que admite rutas públicas / protegidas, el reencaminamiento de inicio de sesión / cierre de sesión, los latidos del corazón para verificaciones de estado, almacena el token de sesión en una cookie, eventos, etc.
Usted podría:
- Modifique el módulo y adjúntelo a su propia API, o
- Use el módulo junto con UserApp (una API de administración de usuarios basada en la nube)
https://github.com/userapp-io/userapp-angular
Si usa UserApp, no tendrá que escribir ningún código del lado del servidor para las cosas del usuario (más que validar un token). Tome el curso en Codecademy para probarlo.
Aquí hay algunos ejemplos de cómo funciona:
Cómo especificar qué rutas deben ser públicas y qué ruta es la forma de inicio de sesión:
$routeProvider.when(''/login'', {templateUrl: ''partials/login.html'', public: true, login: true}); $routeProvider.when(''/signup'', {templateUrl: ''partials/signup.html'', public: true}); $routeProvider.when(''/home'', {templateUrl: ''partials/home.html''});
La ruta
.otherwise()
debe establecerse en el lugar donde desea redirigir a los usuarios después de iniciar sesión. Ejemplo:$routeProvider.otherwise({redirectTo: ''/home''});
Formulario de inicio de sesión con manejo de errores:
<form ua-login ua-error="error-msg"> <input name="login" placeholder="Username"><br> <input name="password" placeholder="Password" type="password"><br> <button type="submit">Log in</button> <p id="error-msg"></p> </form>
Formulario de registro con manejo de errores:
<form ua-signup ua-error="error-msg"> <input name="first_name" placeholder="Your name"><br> <input name="login" ua-is-email placeholder="Email"><br> <input name="password" placeholder="Password" type="password"><br> <button type="submit">Create account</button> <p id="error-msg"></p> </form>
Cerrar sesión de enlace:
<a href="#" ua-logout>Log Out</a>
(Finaliza la sesión y redirige a la ruta de inicio de sesión)
Acceder a las propiedades del usuario:
Se accede a las propiedades del
user
utilizando el servicio deluser
, por ejemplo:user.current.email
O en la plantilla:
<span>{{ user.email }}</span>
Ocultar elementos que solo deberían ser visibles al iniciar sesión:
<div ng-show="user.authorized">Welcome {{ user.first_name }}!</div>
Mostrar un elemento basado en permisos:
<div ua-has-permission="admin">You are an admin</div>
Y para autenticarse en sus servicios de back-end, simplemente use user.token()
para obtener el token de sesión y enviarlo con la solicitud de AJAX. En el back-end, use la API de UserApp (si usa UserApp) para verificar si el token es válido o no.
Si necesita ayuda, ¡házmelo saber!
var _login = function (loginData) {
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
var deferred = $q.defer();
$http.post(serviceBase + ''token'', data, { headers: { ''Content-Type'': ''application/x-www-form-urlencoded'' } }).success(function (response) {
localStorageService.set(''authorizationData'', { token: response.access_token, userName: loginData.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};