AngularJS: ejemplo básico para usar la autenticación en la aplicación de una sola página

12 minutos de lectura

avatar de usuario
soñador

soy nuevo en AngularJS y pasé por su tutorial y lo entendí.

Tengo un backend para mi proyecto listo donde cada uno de los REST los puntos finales deben ser autenticados.

Lo que quiero hacer

a.) Quiero tener una sola página para mi proyecto http://myproject.com.
b.) Una vez que un usuario accede a la URL en el navegador, en función de si el usuario ha iniciado sesión o no, se le presenta una página de inicio/vista o una página de inicio de sesión/vista bajo la misma URL http://myproject.com.
c.) si un usuario no ha iniciado sesión, completa el formulario y el servidor establece un USER_TOKEN en la sesión, por lo que todas las solicitudes adicionales 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? Yo vi aquí y aquí pero no entendía cómo usarlos
b.) ¿Cómo puedo presentar diferentes vistas al usuario en función de si el usuario ha iniciado sesión o no en la misma URL? http://myproject.com

Estoy usando angular.js por primera vez y realmente me confundo sobre cómo comenzar. Cualquier consejo y/o recurso es muy apreciado.

  • Por favor, eche un vistazo al siguiente artículo frederiknakstad.com/…

    – Ajay Beniwal

    22 de abril de 2013 a las 5:27

  • @MichaelCalkins simplemente colocar un enlace no es constructivo. Al menos debería decir lo que el enlace va a proporcionar.

    – Dave Gordon

    27 de junio de 2014 a las 11:28

  • Mi b: Control de acceso y autenticación AngularJS coderwall.com/p/f6brkg

    – Michael J.Calkins

    27/06/2014 a las 20:55

  • El equipo de OAuth tiene una gran biblioteca para esto andreareginato.github.io/oauth-ng

    – factor 10

    30 de julio de 2015 a las 22:05

avatar de usuario
Alex Arvanitidis

Creé un repositorio de github que resume este artículo básicamente: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec

repositorio ng-login Github

Plunker

Voy a tratar de explicar lo mejor posible, espero ayudar a algunos de ustedes por ahí:

(1) aplicación.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 utiliza 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 mantener los datos del usuario. La implementación aquí depende de usted.

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 los roles permitidos 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 está implementado, 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 nuevamente.

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);
        }
    };
} ]);

PD Un error con el autocompletado de datos del formulario como se indica en el primer artículo se puede evitar fácilmente agregando la directiva que se incluye endirectivas.js.

ps2 El usuario puede modificar fácilmente este código para permitir que se vean diferentes rutas o mostrar contenido que no estaba destinado a mostrarse. La lógica DEBE implementarse en el lado del servidor, esta es solo una forma de mostrar las cosas correctamente en su aplicación ng.

  • He estado siguiendo su guía para entender la lógica del lado del cliente. ¡¡Es muy bueno!! Me perdí algo sobre la destrucción manual de sesiones, ¡pero también tenemos que experimentar y romper cosas!

    – Sebastián Alonso

    8 dic 2014 a las 20:06

  • ~~ no estoy seguro si entiendo correctamente esa línea: authService.login() = [...] esos corchetes representarán algo como $http.get(url, {uID, pwd}?~~ ok, busque en el plunker, fue como dije XD

    – netalex

    1 de enero de 2017 a las 16:53


  • ¿Puedes expandir tu respuesta para el lado del servidor?

    – consulta

    14 mayo 2017 a las 18:59

avatar de usuario
soñador

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 un inicio de sesión primero, por lo que el servidor siempre muestra 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 😮

Busque el comentario de “Andrew Joslin”.

https://groups.google.com/forum/?fromgroups=#!searchin/angular/authentication/angular/POXLTi_JUgg/VwStpoWCPUQJ

  • si es una api web? no entendí tu respuesta supongo 🙁

    – Leandro De Mello Fagundes

    30 de julio de 2013 a las 16:54

  • ¿Qué sucede si desea mostrar el nombre de usuario? ¿O si está hablando con un servicio con el nombre de usuario en las URL del punto final?

    – perrygeo

    11 de septiembre de 2013 a las 11:28

  • lo siento, pero no entiendo la respuesta. ¿Cómo manejas la sesión en angular? ¿Dónde está configurado session.user? ¿podría hacer un ejemplo de código de esto, por favor? gracias

    – François Romain

    11 de septiembre de 2013 a las 23:26

  • Las sesiones se manejan en el extremo del cliente y no en el lado del servidor, el cliente guarda el token y lo envía como parte de cada solicitud que realiza. El servidor valida el token y procesa la solicitud

    – soñador

    12 de septiembre de 2013 a las 13:08

  • ¿Podría alguien que lo entienda editar esta respuesta para el resto de nosotros, por favor?

    – Alojz Janez

    17 mayo 2014 a las 22:47

avatar de usuario
Timoteo E. Johansson

Respondí una pregunta similar aquí: AngularJS Authentication + RESTful API


he escrito un Módulo AngularJS por Aplicación de usuario que admite rutas protegidas/públicas, redireccionamiento al iniciar/cerrar sesión, latidos para verificaciones de estado, almacena el token de sesión en una cookie, eventos, etc.

Podrías:

  1. Modifique el módulo y adjúntelo a su propia API, o
  2. Utilice el módulo junto con Aplicación de usuario (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). toma el curso de Codecademy para probarlo

He aquí algunos ejemplos de cómo funciona:

  • Cómo especificar qué rutas deben ser públicas y qué ruta es el formulario 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'});
    

    los .otherwise() La ruta debe configurarse a donde desea que sus usuarios sean redirigidos 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 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 usuario usando el user servicio, por ejemplo: user.current.email

    O en la plantilla: <span>{{ user.email }}</span>

  • Ocultar elementos que solo deberían ser visibles cuando se inicia 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 AJAX. En el back-end, utilice el API de aplicación de usuario (si usa UserApp) para verificar si el token es válido o no.

Si necesitas ayuda, ¡solo házmelo saber!

  • ¿Cómo lo haría? “Modifique el módulo y adjúntelo a su propia API” ?

    – AncientSwordRage

    3 de marzo de 2015 a las 12:08

En angularjs puede crear la parte de la interfaz de usuario, 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, puede usar la especificación OAuth que lo ayudará a crear un mecanismo de seguridad sólido para autenticar al usuario. una vez que construya WebApi con OAuth, debe llamar a esa API para el 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 obtiene el token, solicita los recursos de angularjs con la ayuda de Token y accede al recurso que se mantiene seguro en la Api web con la especificación OAuth.

Por favor, eche un vistazo al siguiente artículo para obtener más ayuda: –

http://bitoftech.net/2014/06/09/angularjs-token-authentication-using-asp-net-web-api-2-owin-asp-net-identity/

Creo que cada respuesta JSON debe contener una propiedad (por ejemplo, {autenticado: falso}) y el cliente debe probarlo cada vez: si es falso, entonces el controlador/servicio angular “redireccionará” a la página de inicio de sesión.

¿Y qué sucede si el usuario captura de JSON y cambia el bool a True?

Creo que nunca debes 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.

  • Mira esto: github.com/witoldsz/angular-http-auth – el interceptor verifica el código de estado de respuesta del servidor y si es 403 (“se requiere inicio de sesión”) transmite un evento, para que pueda capturarlo dentro de la aplicación y mostrar el cuadro de inicio de sesión.

    – aherok

    11 de junio de 2013 a las 20:52

  • Dejen de responderse unos a otros usando respuestas. ¡Para eso están los comentarios!

    – Soviético

    18 de junio de 2013 a las 15:09

  • Sugerencia de @aherok, su comentario debe promoverse a una respuesta, se votará en la parte superior a tiempo. el resto es solo ruido.

    – usuario237419

    04/08/2014 a las 18:33

avatar de usuario
nver abgaryan

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;
 
    };
 

  • Mira esto: github.com/witoldsz/angular-http-auth – el interceptor verifica el código de estado de respuesta del servidor y si es 403 (“se requiere inicio de sesión”) transmite un evento, para que pueda capturarlo dentro de la aplicación y mostrar el cuadro de inicio de sesión.

    – aherok

    11 de junio de 2013 a las 20:52

  • Dejen de responderse unos a otros usando respuestas. ¡Para eso están los comentarios!

    – Soviético

    18 de junio de 2013 a las 15:09

  • Sugerencia de @aherok, su comentario debe promoverse a una respuesta, se votará en la parte superior a tiempo. el resto es solo ruido.

    – usuario237419

    04/08/2014 a las 18:33

¿Ha sido útil esta solución?