신원 인증은 종종 웹에서 적용될 수 있습니다. 이 기사에서는 신원 인증을 적용하는 AngularJS의 기술을 소개합니다.
신분증 인증
가장 일반적인 본인 인증 방법은 사용자 이름(또는 이메일)과 비밀번호를 사용하여 로그인하는 것입니다. 이는 사용자가 자신의 개인 정보를 사용하여 로그인할 수 있도록 로그인 양식을 구현하는 것을 의미합니다. 양식은 다음과 같습니다.
<form name="loginForm" ng-controller="LoginController" ng-submit="login(credentials)" novalidate> <label for="username">Username:</label> <input type="text" id="username" ng-model="credentials.username"> <label for="password">Password:</label> <input type="password" id="password" ng-model="credentials.password"> <button type="submit">Login</button> </form>
이 양식은 Angular 기반 양식이므로 양식을 업로드할 때 ngSubmit 지시어를 사용하여 함수를 트리거합니다. $scope.credentials 개체를 직접 사용하는 대신 업로드 양식 기능에 개인 정보를 전달한다는 점에 유의하세요. 이렇게 하면 함수의 단위 테스트가 더 쉬워지고 현재 컨트롤러 범위에 대한 함수의 결합이 줄어듭니다. 이 컨트롤러는 다음과 같습니다.
.controller('LoginController', function ($scope, $rootScope, AUTH_EVENTS, AuthService) { $scope.credentials = { username: '', password: '' }; $scope.login = function (credentials) { AuthService.login(credentials).then(function (user) { $rootScope.$broadcast(AUTH_EVENTS.loginSuccess); $scope.setCurrentUser(user); }, function () { $rootScope.$broadcast(AUTH_EVENTS.loginFailed); }); };javascript:void(0); })
여기서는 실제 논리가 부족하다는 점을 발견했습니다. 이 컨트롤러는 양식에서 인증 논리를 분리하기 위해 이렇게 만들어졌습니다. 컨트롤러에서 가능한 한 많은 로직을 추출하여 모두 서비스에 넣는 것이 좋습니다. AngularJS의 컨트롤러는 지나치게 많은 작업을 수행하는 대신 $scope(관찰 또는 수동 작업을 사용하여)의 개체만 관리해야 합니다.
세션 변경 알림
신원 인증은 전체 애플리케이션 상태에 영향을 미칩니다. 이러한 이유로 나는 사용자 세션 변경 사항을 알리기 위해 이벤트($broadcast 사용)를 사용하는 것을 선호합니다. 가능한 모든 이벤트 코드를 중간 지점에서 정의하는 것이 좋습니다. 저는 이를 위해 상수를 사용하는 것을 좋아합니다:
.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' })
상수의 좋은 특징은 서비스처럼 다른 곳에 마음대로 주입할 수 있다는 것입니다. 그런 식으로요. 이를 통해 단위 테스트에서 상수를 쉽게 호출할 수 있습니다. 또한 상수를 사용하면 나중에 많은 파일을 변경하지 않고도 쉽게 이름을 바꿀 수 있습니다. 동일한 방법이 사용자 역할에도 적용됩니다.
.constant('USER_ROLES', { all: '*', admin: 'admin', editor: 'editor', guest: 'guest' })
편집자와 관리자에게 동일한 권한을 부여하려면 'editor'를 'admin'으로 변경하면 됩니다. '.
AuthService
신원 인증 및 권한 부여(액세스 제어)와 관련된 로직은 동일한 서비스에 배치하는 것이 가장 좋습니다.
.factory('AuthService', function ($http, Session) { var authService = {}; authService.login = function (credentials) { return $http .post('/login', credentials) .then(function (res) { Session.create(res.data.id, res.data.user.id, res.data.user.role); return res.data.user; }); }; authService.isAuthenticated = function () { return !!Session.userId; }; authService.isAuthorized = function (authorizedRoles) { if (!angular.isArray(authorizedRoles)) { authorizedRoles = [authorizedRoles]; } return (authService.isAuthenticated() && authorizedRoles.indexOf(Session.userRole) !== -1); }; return authService; })
신원 인증 문제에서 벗어나기 위해 다른 서비스(서비스 스타일을 사용하는 싱글톤 개체)를 사용하여 사용자의 세션 정보를 저장합니다. 세션 정보의 세부 사항은 백엔드 구현에 따라 다르지만 보다 일반적인 예를 들어 보겠습니다.
.service('Session', function () { this.create = function (sessionId, userId, userRole) { this.id = sessionId; this.userId = userId; this.userRole = userRole; }; this.destroy = function () { this.id = null; this.userId = null; this.userRole = null; }; return this; })
사용자가 로그인하면 정보는 특정 위치(예: 오른쪽 상단에 있는 사용자 아바타)에 표시되어야 합니다. 이를 달성하려면 사용자 개체는 $scope 개체(전역적으로 호출할 수 있는 개체)에 의해 참조되어야 합니다. $rootScope가 확실한 첫 번째 선택이기는 하지만 $rootScope를 너무 많이 사용하지 않으려고 노력합니다(실제로 전역 이벤트 브로드캐스트에는 $rootScope만 사용합니다). 내가 선호하는 방식은 애플리케이션의 루트 노드나 적어도 DOM 트리보다 높은 위치에 컨트롤러를 정의하는 것입니다. 태그는 좋은 선택입니다.
<body ng-controller="ApplicationController"> ... </body>
ApplicationController는 애플리케이션의 전역 논리를 위한 컨테이너이자 Angular의 실행 메서드를 실행하기 위한 옵션입니다. 따라서 이는 $scope 트리의 루트에 있게 되며 다른 모든 범위는 이로부터 상속됩니다(격리 범위 제외). 이것은 currentUser 객체를 정의하기에 좋은 장소입니다:
.controller('ApplicationController', function ($scope, USER_ROLES, AuthService) { $scope.currentUser = null; $scope.userRoles = USER_ROLES; $scope.isAuthorized = AuthService.isAuthorized; $scope.setCurrentUser = function (user) { $scope.currentUser = user; }; })
실제로 currentUser 객체를 할당하지 않고 범위의 속성만 초기화합니다. currentUser가 나중에 액세스될 수 있도록 합니다. 안타깝게도 하위 범위의 currentUser에 새 값을 할당할 수는 없습니다. 그렇게 하면 섀도우 속성이 생성되기 때문입니다. 이는 기본 유형(문자열, 숫자, 부울, 정의되지 않음 및 null)을 참조 대신 값으로 전달한 결과입니다. 그림자 속성을 방지하려면 setter 함수를 사용해야 합니다. Angular 범위와 프로토타입 상속에 대해 자세히 알아보려면 범위 이해를 읽어보세요.
액세스 제어
신원 인증, 즉 액세스 제어는 실제로 AngularJS에 존재하지 않습니다. 우리는 클라이언트 애플리케이션이기 때문에 모든 소스 코드는 사용자의 손에 있습니다. 사용자가 인증된 인터페이스를 얻기 위해 코드를 변조하는 것을 방지할 수 있는 방법은 없습니다. 우리가 할 수 있는 일은 컨트롤을 보여주는 것뿐입니다. 실제 인증이 필요한 경우 서버 측에서 인증을 수행해야 하지만 이는 이 문서의 범위를 벗어납니다.
요소 표시 제한
AngularJS에는 범위나 표현식에 따라 요소 표시 또는 숨기기를 제어하는 지시어(ngShow, ngHide, ngIf 및 ngSwitch)가 있습니다. 처음 두 개는