AngularJS - 각 루트 및 컨트롤러에서의 로그인 및 인증
나는 Angular를 가지고 있다.yoman, grunt, bower를 사용하여 만든 JS 어플리케이션.
인증을 체크하는 컨트롤러가 있는 로그인 페이지가 있습니다.자격 증명이 올바르면 홈 페이지로 재루팅합니다.
app.module
'use strict';
//Define Routing for app
angular.module('myApp', []).config(['$routeProvider', '$locationProvider',
function($routeProvider,$locationProvider) {
$routeProvider
.when('/login', {
templateUrl: 'login.html',
controller: 'LoginController'
})
.when('/register', {
templateUrl: 'register.html',
controller: 'RegisterController'
})
.when('/forgotPassword', {
templateUrl: 'forgotpassword.html',
controller: 'forgotController'
})
.when('/home', {
templateUrl: 'views/home.html',
controller: 'homeController'
})
.otherwise({
redirectTo: '/login'
});
// $locationProvider.html5Mode(true); //Remove the '#' from URL.
}]);
angular.module('myApp').factory("page", function($rootScope){
var page={};
var user={};
page.setPage=function(title,bodyClass){
$rootScope.pageTitle = title;
$rootScope.bodylayout=bodyClass;
};
page.setUser=function(user){
$rootScope.user=user;
}
return page;
});
LoginController.js
'use strict';
angular.module('myApp').controller('LoginController', function($scope, $location, $window,page) {
page.setPage("Login","login-layout");
$scope.user = {};
$scope.loginUser=function()
{
var username=$scope.user.name;
var password=$scope.user.password;
if(username=="admin" && password=="admin123")
{
page.setUser($scope.user);
$location.path( "/home" );
}
else
{
$scope.message="Error";
$scope.messagecolor="alert alert-danger";
}
}
});
홈페이지에는
<span class="user-info">
<small>Welcome,</small>
{{user.name}}
</span>
<span class="logout"><a href="" ng-click="logoutUser()">Logout</a></span>
서서 loginController
로그인 정보를 확인하고 성공하면 서비스 팩토리에서 사용자 개체를 설정합니다.나는 이것이 맞는지 아닌지 모르겠다.
필요한 것은 사용자가 로그인하면 다른 모든 페이지가 해당 값을 얻을 수 있도록 사용자 개체에 값을 설정합니다.
루트가 변경될 때마다 컨트롤러는 사용자가 로그인하고 있는지 여부를 확인해야 합니다.그렇지 않으면 로그인 페이지로 재루팅됩니다.또, 유저가 이미 로그인하고 있는 경우는, 홈 페이지로 돌아옵니다.컨트롤러는 모든 루트의 credential도 체크해야 합니다.
ng-cookies는 들어봤지만 어떻게 사용하는지 모르겠어요.
제가 본 예 중 대부분은 명확하지 않고 일종의 접근 역할 같은 것을 사용하고 있습니다.나는 그것을 원하지 않는다.로그인 필터만 있으면 됩니다.누가 저한테 아이디어 좀 주실 수 있나요?
이 솔루션은 3가지 부분으로 나뉩니다.사용자의 상태는 서비스에 저장되어 있습니다.루트가 변경되었을 때 감시하는 실행 방식 및 사용자가 요청된 페이지에 액세스할 수 있는지 여부를 확인하는 방식입니다.메인 컨트롤러에서는 사용자의 상태가 변경되었는지 여부를 감시합니다.
app.run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) {
$rootScope.$on('$routeChangeStart', function (event) {
if (!Auth.isLoggedIn()) {
console.log('DENY');
event.preventDefault();
$location.path('/login');
}
else {
console.log('ALLOW');
$location.path('/home');
}
});
}]);
(이것으로 ).Auth
사용자 오브젝트를 처리하고 사용자의 로그 여부를 알 수 있는 메서드가 있습니다.
서비스:
.factory('Auth', function(){
var user;
return{
setUser : function(aUser){
user = aUser;
},
isLoggedIn : function(){
return(user)? user : false;
}
}
})
의 ★★★★★★에서app.run
그럼 을 .$routeChangeStart
되고 됩니다( 「로그 되고 있습니다」, 「로그 되고 있습니다」).isLoggedIn
방법이 처리한다.)사용자가 기록되지 않은 경우 요청된 경로를 로드하지 않고 사용자를 오른쪽 페이지(로그인 경우)로 리디렉션합니다.
loginController
로그인을 처리하려면 로그인 페이지에서 를 사용해야 합니다. '하다'와 하면 요.Auth
기록되지 않다
login Controller:
.controller('loginCtrl', [ '$scope', 'Auth', function ($scope, Auth) {
//submit
$scope.login = function () {
// Ask to the server, do your job and THEN set the user
Auth.setUser(user); //Update the state of the user in the app
};
}])
메인 컨트롤러에서 사용자 상태가 변경되었는지 확인하고 리다이렉트로 응답할 수 있습니다.
.controller('mainCtrl', ['$scope', 'Auth', '$location', function ($scope, Auth, $location) {
$scope.$watch(Auth.isLoggedIn, function (value, oldValue) {
if(!value && oldValue) {
console.log("Disconnect");
$location.path('/login');
}
if(value) {
console.log("Connect");
//Do something when the user is connected
}
}, true);
또 .resolve
의 Atribute 또는 의 예$stateProvider
:
.config(["$stateProvider", function ($stateProvider) {
$stateProvider
.state("forbidden", {
/* ... */
})
.state("signIn", {
/* ... */
resolve: {
access: ["Access", function (Access) { return Access.isAnonymous(); }],
}
})
.state("home", {
/* ... */
resolve: {
access: ["Access", function (Access) { return Access.isAuthenticated(); }],
}
})
.state("admin", {
/* ... */
resolve: {
access: ["Access", function (Access) { return Access.hasRole("ROLE_ADMIN"); }],
}
});
}])
Access
권한에 합니다.
.factory("Access", ["$q", "UserProfile", function ($q, UserProfile) {
var Access = {
OK: 200,
// "we don't know who you are, so we can't say if you're authorized to access
// this resource or not yet, please sign in first"
UNAUTHORIZED: 401,
// "we know who you are, and your profile does not allow you to access this resource"
FORBIDDEN: 403,
hasRole: function (role) {
return UserProfile.then(function (userProfile) {
if (userProfile.$hasRole(role)) {
return Access.OK;
} else if (userProfile.$isAnonymous()) {
return $q.reject(Access.UNAUTHORIZED);
} else {
return $q.reject(Access.FORBIDDEN);
}
});
},
hasAnyRole: function (roles) {
return UserProfile.then(function (userProfile) {
if (userProfile.$hasAnyRole(roles)) {
return Access.OK;
} else if (userProfile.$isAnonymous()) {
return $q.reject(Access.UNAUTHORIZED);
} else {
return $q.reject(Access.FORBIDDEN);
}
});
},
isAnonymous: function () {
return UserProfile.then(function (userProfile) {
if (userProfile.$isAnonymous()) {
return Access.OK;
} else {
return $q.reject(Access.FORBIDDEN);
}
});
},
isAuthenticated: function () {
return UserProfile.then(function (userProfile) {
if (userProfile.$isAuthenticated()) {
return Access.OK;
} else {
return $q.reject(Access.UNAUTHORIZED);
}
});
}
};
return Access;
}])
UserProfile
는 현재 하여 "사용자의 속성"을 합니다.$hasRole
,$hasAnyRole
,$isAnonymous
★★★★★★★★★★★★★★★★★」$isAuthenticated
로직 a)$refresh
메나나나나나나 ( 。
.factory("UserProfile", ["Auth", function (Auth) {
var userProfile = {};
var clearUserProfile = function () {
for (var prop in userProfile) {
if (userProfile.hasOwnProperty(prop)) {
delete userProfile[prop];
}
}
};
var fetchUserProfile = function () {
return Auth.getProfile().then(function (response) {
clearUserProfile();
return angular.extend(userProfile, response.data, {
$refresh: fetchUserProfile,
$hasRole: function (role) {
return userProfile.roles.indexOf(role) >= 0;
},
$hasAnyRole: function (roles) {
return !!userProfile.roles.filter(function (role) {
return roles.indexOf(role) >= 0;
}).length;
},
$isAnonymous: function () {
return userProfile.anonymous;
},
$isAuthenticated: function () {
return !userProfile.anonymous;
}
});
});
};
return fetchUserProfile();
}])
Auth
는 서버 요구를 담당하여 사용자 프로파일을 확인합니다(예를 들어 요구에 부가된 액세스토큰에 링크되어 있습니다).
.service("Auth", ["$http", function ($http) {
this.getProfile = function () {
return $http.get("api/auth");
};
}])
는 JSON 오브젝트를 요구할 때 됩니다.GET api/auth
:
{
"name": "John Doe", // plus any other user information
"roles": ["ROLE_ADMIN", "ROLE_USER"], // or any other role (or no role at all, i.e. an empty array)
"anonymous": false // or true
}
으로, ★★★★★★★★★★★★★★★★★★★★★★★.Access
ui.router
, . . . . . . . .$stateChangeError
이벤트가 발생합니다.
.run(["$rootScope", "Access", "$state", "$log", function ($rootScope, Access, $state, $log) {
$rootScope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
switch (error) {
case Access.UNAUTHORIZED:
$state.go("signIn");
break;
case Access.FORBIDDEN:
$state.go("forbidden");
break;
default:
$log.warn("$stateChangeError event catched");
break;
}
});
}])
「 」를 하고 있는 ngRoute
, . . . . . . . .$routeChangeError
이벤트가 발생합니다.
.run(["$rootScope", "Access", "$location", "$log", function ($rootScope, Access, $location, $log) {
$rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
switch (rejection) {
case Access.UNAUTHORIZED:
$location.path("/signin");
break;
case Access.FORBIDDEN:
$location.path("/forbidden");
break;
default:
$log.warn("$stateChangeError event catched");
break;
}
});
}])
사용자 프로파일은 컨트롤러에서도 액세스 할 수 있습니다.
.state("home", {
/* ... */
controller: "HomeController",
resolve: {
userProfile: "UserProfile"
}
})
UserProfile
에는, 되어 있습니다.GET api/auth
:
.controller("HomeController", ["$scope", "userProfile", function ($scope, userProfile) {
$scope.title = "Hello " + userProfile.name; // "Hello John Doe" in the example
}])
UserProfile
할 때 .Access
는 새로운 사용자 프로파일을 사용하여 루트를 처리할 수 있습니다.할 수 .UserProfile.$refresh()
시 다음 중 하나:
.service("Auth", ["$http", function ($http) {
/* ... */
this.signIn = function (credentials) {
return $http.post("api/auth", credentials).then(function (response) {
// authentication succeeded, store the response access token somewhere (if any)
});
};
}])
.state("signIn", {
/* ... */
controller: "SignInController",
resolve: {
/* ... */
userProfile: "UserProfile"
}
})
.controller("SignInController", ["$scope", "$state", "Auth", "userProfile", function ($scope, $state, Auth, userProfile) {
$scope.signIn = function () {
Auth.signIn($scope.credentials).then(function () {
// user successfully authenticated, refresh UserProfile
return userProfile.$refresh();
}).then(function () {
// UserProfile is refreshed, redirect user somewhere
$state.go("home");
});
};
}])
각 루트의 커스텀 동작을 정의하는 가장 간단한 방법은 다음과 같습니다.
1)routes.js
예: 새새(((((((((((((((((:requireAuth
)를 지정합니다
angular.module('yourApp').config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'templates/home.html',
requireAuth: true // our custom property
})
.when('/login', {
templateUrl: 'templates/login.html',
})
.otherwise({
redirectTo: '/home'
});
})
2) 않은 2) 내부 요소에 바인딩되지 않은 경우ng-view
(각(각)$routeProvider
이(가) 를 합니다.newUrl
가지고 있다requireAuth
에 따른 을 하다
angular.module('YourApp').controller('YourController', function ($scope, $location, session) {
// intercept the route change event
$scope.$on('$routeChangeStart', function (angularEvent, newUrl) {
// check if the custom property exist
if (newUrl.requireAuth && !session.user) {
// user isn’t authenticated
$location.path("/login");
}
});
});
몇 달 전에 Angular에서 사용자 등록 및 로그인 기능을 설정하는 방법에 대해 글을 썼는데, http://jasonwatmore.com/post/2015/03/10/AngularJS-User-Registration-and-Login-Example.aspx에서 확인하실 수 있습니다.
있는지 합니다.$locationChangeStart
이벤트, 이것은 제 메인 앱입니다.
(function () {
'use strict';
angular
.module('app', ['ngRoute', 'ngCookies'])
.config(config)
.run(run);
config.$inject = ['$routeProvider', '$locationProvider'];
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'home/home.view.html',
controllerAs: 'vm'
})
.when('/login', {
controller: 'LoginController',
templateUrl: 'login/login.view.html',
controllerAs: 'vm'
})
.when('/register', {
controller: 'RegisterController',
templateUrl: 'register/register.view.html',
controllerAs: 'vm'
})
.otherwise({ redirectTo: '/login' });
}
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];
function run($rootScope, $location, $cookieStore, $http) {
// keep user logged in after page refresh
$rootScope.globals = $cookieStore.get('globals') || {};
if ($rootScope.globals.currentUser) {
$http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
}
$rootScope.$on('$locationChangeStart', function (event, next, current) {
// redirect to login page if not logged in and trying to access a restricted page
var restrictedPage = $.inArray($location.path(), ['/login', '/register']) === -1;
var loggedIn = $rootScope.globals.currentUser;
if (restrictedPage && !loggedIn) {
$location.path('/login');
}
});
}
})();
이 방법이 가장 편하다고 생각하지만, 아마도 개인적인 취향일 것입니다.
로그인 루트(및 기타 어나니머스 루트)를 지정할 때(예: /register, /logout, /refresh)토큰 등) 추가:
allowAnonymous: true
이런 거 있잖아요
$stateProvider.state('login', {
url: '/login',
allowAnonymous: true, //if you move this, don't forget to update
//variable path in the force-page check.
views: {
root: {
templateUrl: "app/auth/login/login.html",
controller: 'LoginCtrl'
}
}
//Any other config
}
"allowAnonymous: false"를 지정할 필요가 없습니다.없을 경우 false로 간주됩니다.대부분의 URL이 강제로 인증되는 앱에서는 이 작업이 덜 수행됩니다.또한 새 URL에 추가하는 것을 잊은 경우 익명 URL이 보호됩니다.반대로 하면, 「require」를 지정해 주세요.Authentication: true"라는 메시지가 표시되고 URL에 추가하지 않으면 기밀 페이지가 일반에 유출됩니다.
다음으로 코드 설계에 가장 적합하다고 생각되는 장소에서 실행할 수 있습니다.
//I put it right after the main app module config. I.e. This thing:
angular.module('app', [ /* your dependencies*/ ])
.config(function (/* you injections */) { /* your config */ })
//Make sure there's no ';' ending the previous line. We're chaining. (or just use a variable)
//
//Then force the logon page
.run(function ($rootScope, $state, $location, User /* My custom session obj */) {
$rootScope.$on('$stateChangeStart', function(event, newState) {
if (!User.authenticated && newState.allowAnonymous != true) {
//Don't use: $state.go('login');
//Apparently you can't set the $state while in a $state event.
//It doesn't work properly. So we use the other way.
$location.path("/login");
}
});
});
app.module
'use strict';
// Declare app level module which depends on filters, and services
var app= angular.module('myApp', ['ngRoute','angularUtils.directives.dirPagination','ngLoadingSpinner']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'loginCtrl'});
$routeProvider.when('/home', {templateUrl: 'partials/home.html', controller: 'homeCtrl'});
$routeProvider.when('/salesnew', {templateUrl: 'partials/salesnew.html', controller: 'salesnewCtrl'});
$routeProvider.when('/salesview', {templateUrl: 'partials/salesview.html', controller: 'salesviewCtrl'});
$routeProvider.when('/users', {templateUrl: 'partials/users.html', controller: 'usersCtrl'});
$routeProvider.when('/forgot', {templateUrl: 'partials/forgot.html', controller: 'forgotCtrl'});
$routeProvider.otherwise({redirectTo: '/login'});
}]);
app.run(function($rootScope, $location, loginService){
var routespermission=['/home']; //route that require login
var salesnew=['/salesnew'];
var salesview=['/salesview'];
var users=['/users'];
$rootScope.$on('$routeChangeStart', function(){
if( routespermission.indexOf($location.path()) !=-1
|| salesview.indexOf($location.path()) !=-1
|| salesnew.indexOf($location.path()) !=-1
|| users.indexOf($location.path()) !=-1)
{
var connected=loginService.islogged();
connected.then(function(msg){
if(!msg.data)
{
$location.path('/login');
}
});
}
});
});
로그인 서비스js
'use strict';
app.factory('loginService',function($http, $location, sessionService){
return{
login:function(data,scope){
var $promise=$http.post('data/user.php',data); //send data to user.php
$promise.then(function(msg){
var uid=msg.data;
if(uid){
scope.msgtxt='Correct information';
sessionService.set('uid',uid);
$location.path('/home');
}
else {
scope.msgtxt='incorrect information';
$location.path('/login');
}
});
},
logout:function(){
sessionService.destroy('uid');
$location.path('/login');
},
islogged:function(){
var $checkSessionServer=$http.post('data/check_session.php');
return $checkSessionServer;
/*
if(sessionService.get('user')) return true;
else return false;
*/
}
}
});
세션 서비스js
'use strict';
app.factory('sessionService', ['$http', function($http){
return{
set:function(key,value){
return sessionStorage.setItem(key,value);
},
get:function(key){
return sessionStorage.getItem(key);
},
destroy:function(key){
$http.post('data/destroy_session.php');
return sessionStorage.removeItem(key);
}
};
}])
loginCtrl.js
'use strict';
app.controller('loginCtrl', ['$scope','loginService', function ($scope,loginService) {
$scope.msgtxt='';
$scope.login=function(data){
loginService.login(data,$scope); //call login service
};
}]);
사용할 수 있습니다.resolve
:
angular.module('app',[])
.config(function($routeProvider)
{
$routeProvider
.when('/', {
templateUrl : 'app/views/login.html',
controller : 'YourController',
controllerAs : 'Your',
resolve: {
factory : checkLoginRedirect
}
})
}
그리고 해결의 기능은 다음과 같습니다.
function checkLoginRedirect($location){
var user = firebase.auth().currentUser;
if (user) {
// User is signed in.
if ($location.path() == "/"){
$location.path('dash');
}
return true;
}else{
// No user is signed in.
$location.path('/');
return false;
}
}
Firebase는 또한 옵서버를 설치할 수 있는 방법을 가지고 있습니다. 나는 그것을 내부에 설치할 것을 권장합니다..run
:
.run(function(){
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
console.log('User is signed in.');
} else {
console.log('No user is signed in.');
}
});
}
예를 들어 어플리케이션에는 ap과 auc라는2개의 사용자가 있습니다.각 루트에 추가 속성을 전달하고 $routeChangeStart에서 얻은 데이터를 기반으로 루팅을 처리합니다.
이것을 시험해 보세요.
angular.module("app").config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/ap', {
templateUrl: 'template1.html',
controller: 'template1',
isAp: 'ap',
}).
when('/auc', {
templateUrl: 'template2.html',
controller: 'template2',
isAp: 'common',
}).
when('/ic', {
templateUrl: 'template3.html',
controller: 'template3',
isAp: 'auc',
}).
when('/mup', {
templateUrl: 'template4.html',
controller: 'template4',
isAp: 'ap',
}).
when('/mnu', {
templateUrl: 'template5.html',
controller: 'template5',
isAp: 'common',
}).
otherwise({
redirectTo: '/ap',
});
}]);
app.filename:
.run(['$rootScope', '$location', function ($rootScope, $location) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (next.$$route.isAp != 'common') {
if ($rootScope.userTypeGlobal == 1) {
if (next.$$route.isAp != 'ap') {
$location.path("/ap");
}
}
else {
if (next.$$route.isAp != 'auc') {
$location.path("/auc");
}
}
}
});
}]);
모두, 클라이언트측의 세션을 염려하는 큰 솔루션을 제안하고 있습니다.상태/url이 변경되면 임시로 데이터를 로드하기 위해 Ajax 호출을 하는 것 같습니다.
Note :- To Save user's data you may use `resolve` feature of `ui-router`.
Check cookie if it exist load template , if even cookies doesn't exist than
there is no chance of logged in , simply redirect to login template/page.
이제 api를 사용하여 서버에서 ajax 데이터가 반환됩니다.이제 포인트가 적용되어 로그인한 사용자의 상태에 따라 서버를 사용하여 표준 반환 유형을 반환합니다.이러한 리턴 코드를 확인하고 컨트롤러에서 요청을 처리합니다.주의: - Ajax 호출이 네이티브로 필요하지 않은 컨트롤러의 경우 다음과 같이 서버에 빈 요청을 호출할 수 있습니다.server.location/api/checkSession.php
이건 CheckSession입니다.php
<?php/ANY_LANGUAGE
session_start();//You may use your language specific function if required
if(isset($_SESSION["logged_in"])){
set_header("200 OK");//this is not right syntax , it is just to hint
}
else{
set_header("-1 NOT LOGGED_IN");//you may set any code but compare that same
//code on client side to check if user is logged in or not.
}
//thanks.....
컨트롤러 내부의 클라이언트 측 또는 기타 응답과 같이 임의의 서비스를 통한
$http.get(dataUrl)
.success(function (data){
$scope.templateData = data;
})
.error(function (error, status){
$scope.data.error = { message: error, status: status};
console.log($scope.data.error.status);
if(status == CODE_CONFIGURED_ON_SERVER_SIDE_FOR_NON_LOGGED_IN){
//redirect to login
});
주의:- 내일 또는 나중에 업데이트하겠습니다.
두 개의 주요 사이트에서 사용자 인증을 확인해야 합니다.
- 상태를 때 를 사용하여 합니다.
'$routeChangeStart'
(복귀) - 가로채기를 사용하여 각도로부터 $http 요구가 전송되는 경우.
언급URL : https://stackoverflow.com/questions/20969835/angularjs-login-and-authentication-in-each-route-and-controller
'programing' 카테고리의 다른 글
Java에서 Jackson JSON 역직렬화 중 누락된 속성 무시 (0) | 2023.02.26 |
---|---|
WebMvc 주석 의미 사용 (0) | 2023.02.26 |
진행률 요소에 AJAX 업로드 상태 표시 (0) | 2023.02.26 |
POST(ajax)를 통해 JSON 데이터를 전송하고 컨트롤러(MVC)로부터 json 응답을 수신합니다. (0) | 2023.02.26 |
리액트 라우터의 루트 천이에 대한 응답으로 Redx 액션을 기동하다 (0) | 2023.02.26 |