Route Guard CanActivate trong Angular 2+

mọi người cho mình hỏi! mình có một trượng hợp như sau!
vào trang /login => login vào hệ thống => vào một trang abc gì đó. sau đó người dùng lại gõ /login
+) điều mình muốn là khi gõ /login thì phải ở lại trang hiện tại vì đã login rồi. nhưng hiện tại mình chưa tìm ra cách giải quyết mong các ae chỉ dáo :frowning:

Check nếu đã tồn tại thông tin đăng nhập trong session thì redirect về trang chính thôi.

1 Like

Câu hỏi của bạn thật khó hiểu, chả biết chỗ nào đễ mà gãi giúp :smiley:

tìm một hệ thống route nào đó
đặt callback vào event chuyển route
nếu người ta vào login thì test xem đã login chưa
nếu login rồi thì reject, trang hiện tại vẫn sẽ như cũ
Angular 1 có cái này: https://ui-router.github.io

1 Like

ý là khi user đã đăng nhập rồi! và hiện tại user đang trong 1 trang nào đó!
nhưng user lại gõ trên URL là /login về logic thì không dc vào trang này nữa! mình muốn nó ở chính trang hiện tại nhưng việc check router hiện tại lấy trong constructor của router là /login luôn!
còn về việc check isAuthenticated thì hk phải!

mình muốn no về trang hiện tại chứ hk ra dashboard . huhu tìm hoài hk ra

Mình thì không rõ cho lắm. Giả sử thế này, bạn gõ /login vào address bar, các thiết lập angular trước đó mất hết, từ module, root service, router đến injector. Web page load lại toàn bộ từ đầu, tạo resolve các module lại, tạo injector hierachy lại, và tạo cả router nữa.

Lúc này thì router mất đi thông tin về route trước đó nên không thể navigate() được. Vì vậy phương án sử dụng route snapshot lấy url, rồi dùng router để navigate trên url đó không khả thi. Mình nghĩ bạn đang bị bí chỗ này.

Mình search thì thấy 1 cái khác có thể thay thế cho router, nhưng lại không thuộc bên @angular/router. Class đó là Location ở trong @angular/common, được viết dựa trên window.location của JS thuần. Location có method back() để trở về url trước đó. Tuy nhiên, mình không biết cái Location có làm break cơ chế route của Angular Router hay không nữa.

Case này mình chưa gặp nên chỉ có thể gợi ý bạn dùng Location của @angular/common thôi nhé. :yum:

https://angular.io/api/common/Location

2 Likes

tức là khi gõ /login nó hiện ra trang login phải không? mà bạn không muốn điều này?
giao dien login
dnh_man%20hinh%20chinh
giao dien login done
dnh_home
giao dien home
dnh_product
giao dien khi gõ login
dnh_go%20login
bạn kiểm tra tình trạng đăng nhập rồi set cái router trở về “/”
Nhiều khi nên làm demo nho nhỏ như thế này, rồi xem như template để phát triển trong thực tế

Tặng bạn cái đoạn source bài này, bạn tự nghiên cứu thử (độ rày mình cũng chán cái thằng angular này rồi :joy:)


    	<h4>login ngroute2</h4>
<script type="text/javascript" src="<?php echo base_url(); ?>js/angular.min.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>js/angular-route.js"></script>
<script>
	var url = "<?php echo $url; ?>";
	var app = angular.module('myApp', ['ngRoute']);
	app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
		$routeProvider
			.when('/', {
				templateUrl: 'home.html',
				controller: 'homeCtrl',
			})

			.when('/product', {
				templateUrl: 'product.html',
				controller: 'productCtrl'
			})
			.when('/contact', {
				templateUrl: 'contact.html',
				controller: 'contactCtrl'
			})
			.when('/test', {
				template: [
					'{{msg}}',
				].join(''),
				controller: 'testCtrl'
			})
			.when('/login', {
				templateUrl: 'login.html',
				controller: 'loginCtrl'
			})
			.when('/qluser', {
				template: [
					'{{msg}}',
				].join(''),
				controller: 'qluserCtrl'
			})


			.otherwise({
				redirectTo: '/'
			});
	}]);


	app.run(function ($rootScope, $location, auth) {
		$rootScope.init = function () {
			auth.all_userdata().then(function (res) {
				$rootScope.all_userdata = res;
			});
		};
		$rootScope.init();
		$rootScope.user_info = { logged: 0, user: "", quyen: [], menu: [] };
		$rootScope.$watch("user_info", function (n, o) {
			if (n.user !== o.user) {
				auth.all_userdata().then(function (res) {
					$rootScope.all_userdata = res;
				});
			}
		}, true);

		auth.chk_auth().then(function (res) {
			$rootScope.user_info = res;
		});
		$rootScope.$on('$locationChangeStart', function (event, next, current) {
			var chk_quyen = auth.chk_quyen($rootScope.user_info, $location.path());
			if (chk_quyen == 0) {
				$location.path("/login");
			}
		});
		$rootScope.$on("logout", function () {
			auth.logout().then(function (res) {
				if (res.logged == 0) {
					$rootScope.user_info = res;
					$location.path("/login");
				}
			});
		});
		$rootScope.$on("login", function (event, args) {
			var nd = args;
			auth.chk_user_pass(nd.user, nd.pass).then(function (res) {
				if (res.logged == 1) {
					$location.path("/");
				}
				$rootScope.user_info = res;
			});
		});
	});

	app.controller("homeCtrl", function ($scope) {
		$scope.msg = "this is home";
	});
	app.controller("qluserCtrl", function ($scope) {
		$scope.msg = "this is qluserCtrl";
	});

	app.controller("testCtrl", function ($scope) {
		$scope.msg = "this is test and crt template";
	});
	app.controller("productCtrl", function ($scope) {
		$scope.msg = "this is product";
	});
	app.controller("contactCtrl", function ($scope) {
		$scope.msg = "this is contact";
	});
	app.controller("loginCtrl", function ($scope) {
		$scope.msg = "this is login";
		$scope.nd = { user: "thuc", pass: "thuc" };
		$scope.on_dang_nhap = function () {
			$scope.$emit("login", $scope.nd);
		};
	});

	app.directive("menuDir", function ($location) {
		return {
			restrict: "EA",
			scope: {
				userInfo: "=",
				menu: "="
			},
			template: [
				'<div style="border-bottom:1px solid blue; padding:5px;" >',
				'<span ng-repeat="x in ds">',
				'<a  ng-class="menuClass(x.id)" href="#/{{x.id}}">{{x.ten}}</a> <span ng-if=" $last==false " >|</span> ',
				'</span>',
				'</div>',
			].join(''),
			link: function (scope, element, attr, ctrl) {
				scope.init = function () {
					scope.lay_ds();
				};
				scope.menuClass = function (page) {
					var current = $location.path().substring(1);//loai ky tu dau
					return page === current ? "select" : "";
				};
				scope.lay_ds = function () {
					var ds = angular.copy(scope.userInfo.menu);//angular.copy(scope.menu);
					scope.ds = [];
					for (x in ds) {
						scope.ds.push(ds[x]);
					}
				};
				scope.$watch("userInfo", function (n, o) {
					scope.lay_ds();
				}, true);
				scope.init();
			}
		};
	});//end directive

	app.directive("menuUser", function (auth, $location, $rootScope) {
		return {
			restrict: "EA",
			scope: {
				userInfo: "="
			},
			template: [
				'<a ng-if=" userInfo.logged==0  " ng-href="#/login">Login</a>',
				'<span ng-if=" userInfo.logged==1  ">{{userInfo.user}}, ',
				'<a href="javascript:void(0);" ng-click="on_logout();">Logout</a>',
				'</span>',
			].join(''),
			link: function (scope, element, attr, ctrl) {
				scope.on_logout = function () {
					scope.$emit("logout");
				};
			}
		};
	});//end directive 

	app.factory("auth", function ($http, $q, $rootScope) {
		return {
			get_ten: function () { return _ten; },
			all_userdata: function () {
				var def = $q.defer();
				$http.get(url + "/all_userdata").then(function (res) {
					def.resolve(res.data.msg);
				});
				return def.promise;
			},
			chk_user_pass: function (user, pass) {
				var def = $q.defer();
				$http({
					url: url + "/chk_user_pass",
					method: "POST",
					headers: { 'Content-Type': 'application/json' },
					data: { user: user, pass: pass },
				}).success(function (data, status, headers, config) {
					def.resolve(data);
				}).error(function (data, status, headers, config) {
					def.reject("error from auth : " + status);//(error.message);
				});
				return def.promise;
			},
			logout: function () {
				var def = $q.defer();
				$http.get(url + "/logout").then(function (res) {
					def.resolve(res.data)
				});
				return def.promise;
			},
			chk_auth: function () {
				var def = $q.defer();
				$http({
					url: url + "/chk_auth",
					method: "POST",
					headers: { 'Content-Type': 'application/json' },
					data: {},
				}).success(function (data, status, headers, config) {
					def.resolve(data);
				}).error(function (data, status, headers, config) {
					def.reject("error from auth : " + status);//(error.message);
				});
				return def.promise;
			},
			chk_quyen: function (user_info, path) {
				var kq = 0;
				if (path == "/" || path == "/login") {//home and login is public
					kq = 1;
				} else {
					var quyen = $rootScope.user_info.quyen;
					if (quyen.indexOf(path.substring(1)) != -1) {
						kq = 1;
					}
				}
				return kq;
			},
		}
	});

</script>
<style>
	.select {
		background-color: yellow;
	}
</style>

<div ng-app="myApp" style="border:1px solid silver; padding:10px;">

	<div class="container-fluid">
		<!--just for test-->
		<!--<div>{{user_info}}</div>-->
		<!--just for test-->
		<div class="row">
			<div class="col-lg-5 box">

				<h3 style="border-bottom:1px solid gray">Some Application</h3>
				<div menu-dir user-info="user_info" menu="menu"></div>
				<div style="text-align:right;">
					<div menu-user user-info="user_info"></div>
				</div>
				<div ng-view style="border:1px solid blue; padding:10px;"></div>
				<div style="border-top:1px solid gray;">This is footer</div>

			</div>
			<div class="col-lg-7">
				<!--just for test-->
				<pre>{{all_userdata | json}}</pre>
				<!--just for test-->
			</div>
		</div>
	</div>

	<script type="text/ng-template" id="home.html">
        <p>{{msg}}</p>
    </script>
	<script type="text/ng-template" id="product.html">
        <p>{{msg}}</p>
    </script>
	<script type="text/ng-template" id="contact.html">
        <p>{{msg}}</p>
    </script>
	<!--important-->
	<script type="text/ng-template" id="login.html">
        <p>{{msg}}</p>
		user : <input type="text" ng-model="nd.user" /><br>
		pass : <input type="text" ng-model="nd.pass"/><br>
		<button ng-click=" on_dang_nhap(); ">Dang nhap</button>
    </script>
	<!--important-->

</div>    


Hope to help you!!!

1 Like

cảm ơn huynh! nhưng mình bị vấn đề cụ thể bên angular 2+ ! logic thì phần đó ok rồi

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?