尝试访问受保护的页面时需要尝试登录才能正常工作 [英] Trying to get login required to work when trying to access protected pages

查看:96
本文介绍了尝试访问受保护的页面时需要尝试登录才能正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • Django 1.11
  • Django REST Framework(DRF)3.6
  • DRF-JWT 1.10
  • AngularJS 1.6.5
  • ui-router 1.0.3

所有这项技术都是全新的,并且已经困扰了该问题好几天了.通过以下类和存储库了解了该堆栈(减去了我刚刚切换到一个星期的UI-router)的信息:

Fairly new to all of this technology and have been messing with this issue for several days now. Learned about this stack (minus UI-router which I just switched to a week ago) through the following class and repository:

https://www.udemy.com/django-angularjs/learn /v4/概述

https://github.com/codingforentrepreneurs/Django-AngularJS/tree /master/src

以下是与我的问题最相关的目录:

These are the directories that are probably the most relevant to my issue:

配置和JS: https://github .com/codingforentrepreneurs/Django-AngularJS/tree/master/src/static/js/app

需要登录的拦截器: https://github.com/codingforentrepreneurs/Django-AngularJS/tree/master/src/static/js/app/core/interceptors

服务,需要登录并使用拦截器的页面:

Service, pages where login is required, and interceptor is utilized: https://github.com/codingforentrepreneurs/Django-AngularJS/tree/master/src/static/js/app/core/comment

我正在尝试使其适应我的项目.

I am trying to adapt it for my project.

我已经阅读了一些纯粹出于此目的而使用ui-router的教程,但是它们似乎没有使用DRF-JWT或缺少像我这样的新手需要的重要步骤.

I have read several tutorials on using ui-router purely for this purpose, but they don't seem to use DRF-JWT or are missing important steps that a newb like me needs.

无论如何,我有两个网址:

Anyway, I have two urls:

/

/dashboard

前者是登录名,/dashboard需要授权,并且如果该人未登录,则应路由到/.在我开始尝试实现此功能之前,可以直接输入/dashboard而无需进行身份验证和查看它.我已经验证过,当一个人通过DRF-JWT登录令牌时,将生成该令牌并将其写入cookie,因为我成功登录后可以console.log将其写入cookie.

The former is the login, /dashboard requires authorization and should route to / if the person isn't logged in. Before I started trying to implement this, one could just type in /dashboard without being authenticated and view it. I have verified that when a person logins in the token through DRF-JWT it is being generated and written to the cookie as I can console.log it on successful login.

由于我一直在尝试实现这一点,所以我什至无法加载/.我遇到无法解决的$injector:modulerr问题.

Since I have been trying to implement this, I can't even get / to load. I get an $injector:modulerr issue that I can't resolve.

代码时间:

更改后,我会得到$injector:modulerr:

// dashboard.module.js

angular.module('dashboard', ['chart.js']);

收件人

// dashboard.module.js

angular.module('dashboard', ['chart.js', 'interceptors']);

其他命令式JS:

// login_required.service.js

'use strict';

angular.
    module('interceptors').
        factory('LoginRequiredInterceptor', function($cookies, $location) {
            return function(response) {
                console.log('working')
                console.log('interceptor error')
                console.log(response)
                if (response.status == 401){
                    var currentPath = $location.path();
                    console.log(currentPath)
                    if (currentPath == '/') {
                        $location.path('/')
                    } else {
                        $location.path('/').search('next', currentPath)
                    }
                }
            }
        })

-

// interceptors.module.js

'use strict';

angular.module('interceptors', ['ngCookies']);

-

// dashboard.component.js

'use strict';

angular.module('dashboard').
    component('dashboard', {
        templateUrl: '/api/templates/dashboard.html',
        controller: function($cookies, $location, $stateParams, $rootScope, $scope) {
             // Nothing at this point
        }
    });

我尚未从上面克隆的项目中真正更新过以下内容:

Really haven't updated the below from the project I cloned it from above:

// dashboard.service.js

'use strict';

angular.
    module('dashboard').
        factory('Dashboard', function(LoginRequiredInterceptor, $cookies, $httpParamSerializer, $location, $resource){

            var token = $cookies.get("token")
            if (token){
                commentCreate["headers"] = {"Authorization": "JWT " + token}
                commentDelete["headers"] = {"Authorization": "JWT " + token}
                commentUpdate["headers"] = {"Authorization": "JWT " + token}
            }

            return $resource(url, {}, {
                query: commentQuery,
                get: commentGet,
                create: commentCreate,
                delete: commentDelete,
                update: commentUpdate,
            })

        });

最后,主要配置:

// app.config.js

'use strict';

angular.module('app').
    config(
        function(
            $locationProvider,
            $resourceProvider,
            $stateProvider,
            $urlRouterProvider,
            $authProvider
            ) {

            // Enable HTML5 mode
            $locationProvider.html5Mode({
                enabled:true
            })

            // Remove trailing slashes to avoid API issues
            $resourceProvider.defaults.stripTrailingSlashes = false;

            // Route handling if the URL does not match any of the below
            // it will send the user to the login screen
            $urlRouterProvider.otherwise('/');

            $stateProvider
                // The top URL (app/) is the login screen
                .state('/', {
                    url: '/',
                    views: {
                        'content@': {
                            component: 'login'
                        }
                    }
                })

                // Logout and reroute to the login screen
                .state('logout', {
                    redirectTo: '/'
                })

                // After successful login, the user is brought to the dashboard
                // Parent of the states below it
                .state('dashboard', {
                    url: '/dashboard',
                    views: {
                        'content@': {
                            component: 'dashboard'
                        }
                    },
                })

                // Test State1
                .state('dashboard.test1', {
                    views: {
                        'dashboard@dashboard': {
                            template: '<p style="position: absolute;top: 110%; left: 50%">Test1</p>'
                        }
                    }
                })

                // Test State2
                .state('dashboard.test2', {
                    views: {
                        'dashboard@dashboard': {
                            template: '<p style="position: absolute;top: 50%; left: 50%">Test2</p>'
                        }
                    }
                })
    });

此外,<scripts>我正在读(在我的<body>标签底部):

Also, <scripts> I am reading in (at the bottom of my <body> tag):

<!-- base.html -->

<!-- Angular 1.x and Bootstrap UI libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js" integrity="sha256-zBy1l2WBAh2vPF8rnjFMUXujsfkKjya0Jy5j6yKj0+Q=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-cookies.min.js" integrity="sha256-tVvnbUkwgprwLlmcKyx6/dz+KifqSSJ41vvUGvL72QM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-resource.min.js" integrity="sha256-J9EYt6krcoClMPGCdI0BA5vhMVHU/lu9vSnhbx0vfAI=" crossorigin="anonymous"></script>
<!--
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-route.min.js" integrity="sha256-E6XubcgT4a601977ZZP4Yw/0UCB2/Ex+Bazst+JRw1U=" crossorigin="anonymous"></script>
-->

<!-- UI libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js" integrity="sha256-w3THDDhkzdjMczax74BBlkhjBxWIGisjArsP5wIQSHc=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js" integrity="sha256-tyfWW2LtJQNI+l3F0h6xDV/ij6Mfn8lwSKHWOsmEgXM=" crossorigin="anonymous"></script>

<!-- Misc 3rd Part Libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/satellizer/0.14.1/satellizer.min.js" integrity="sha256-pcZRGEYkbl74zjS+YusQRvVWoFcwZTHLjmDCvbdX2ec=" crossorigin="anonymous"></script>

<!-- Chart related libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js" integrity="sha256-SiHXR50l06UwJvHhFY4e5vzwq75vEHH+8fFNpkXePr0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-chart.js/1.1.1/angular-chart.min.js" integrity="sha256-ydmVOl8gRR1E4yD1OC/aQdLNPCIKXSHIpl9yOu8EWek=" crossorigin="anonymous"></script>

<!-- Core application settings -->
<script src='{% static "js/app.module.js" %}' ></script>
<script src='{% static "js/app.config.js" %}' ></script>

<!-- Global application components -->
<script src='{% static "js/navbar/navbar.module.js" %}' ></script>
<script src='{% static "js/navbar/navbar.directive.js" %}' ></script>
<script src='{% static "js/sidebar/sidebar.module.js" %}' ></script>
<script src='{% static "js/sidebar/sidebar.directive.js" %}' ></script>

<!-- Page specific application componenets -->
<script src='{% static "js/login/login.module.js" %}' ></script>
<script src='{% static "js/login/login.component.js" %}' ></script>
<script src='{% static "js/dashboard/dashboard.module.js" %}' ></script>
<script src='{% static "js/dashboard/dashboard.component.js" %}' ></script>

让我知道是否还有其他帮助.

Let me know if anything else would be helpful.

推荐答案

好吧,我发现了一个似乎对我有用的解决方案,它很简单.可能有几个问题,因此非常感谢您提供有关为什么不这样做的反馈.

Well, I found a solution that seems to be working for me and is rather simple. There could be several issues with it, so feedback on why not to do this would be greatly appreciated.

我几乎放弃了拦截器,服务等.

I pretty much ditched the interceptors, services, etc.

同样,我实际上只有2个URL:'/''/dashboard'.前者是登录名,后者是用户可用的所有工具(最终是几十个工具)的位置,但它们将是父级dashboard的子视图.您可以在这里开始看到它:

Again, I really only have 2 URLs: '/' and '/dashboard'. The former is the login and the latter is where all the tools available to a user will be (eventually several dozen tools), but they will be child views of the parent dashboard. You can start to see this here:

// app.config.js

'use strict';

angular.module('app').
    config(
        function(
            $locationProvider,
            $resourceProvider,
            $stateProvider,
            $urlRouterProvider,
            $authProvider
            ) {

            // Enable HTML5 mode
            $locationProvider.html5Mode({
                enabled:true
            })

            // Remove trailing slashes to avoid API issues
            $resourceProvider.defaults.stripTrailingSlashes = false;

            // Route handling if the URL does not match any of the below
            // it will send the user to the login screen
            $urlRouterProvider.otherwise('/');

            $stateProvider
                // The top URL (app/) is the login screen
                .state('/', {
                    url: '/',
                    views: {
                        'content@': {
                            component: 'login'
                        }
                    }
                })

                // Logout and reroute to the login screen
                .state('logout', {
                    redirectTo: '/'
                })

                // After successful login, the user is brought to the dashboard
                // Parent of the states below it
                .state('dashboard', {
                    url: '/dashboard',
                    views: {
                        'content@': {
                            component: 'dashboard'
                        }
                    },
                })

                // Test child State1
                .state('dashboard.test1', {
                    views: {
                        'dashboard@dashboard': {
                            template: '<p style="position: absolute;top: 110%; left: 50%">Test1</p>'
                        }
                    }
                })

                // Test child State2
                .state('dashboard.test2', {
                    views: {
                        'dashboard@dashboard': {
                            template: '<p style="position: absolute;top: 50%; left: 50%">Test2</p>'
                        }
                    }
                })
    });

这是将JWT令牌写入Cookie的登录名.

Here is the login where the JWT token is written to the cookie.

// login.component.js

'use strict';

angular.module('login').
    component('login', {
        templateUrl: 'api/templates/login.html',
        controller: function($cookies, $http, $location, $stateParams, $rootScope, $scope) {
            var loginUrl = 'api/users/login/'
            $scope.loginError = {}
            $scope.user = {}

            $scope.$watch(function() {
                if ($scope.user.password) {
                    $scope.loginError.password = ''
                } else if ($scope.user.username) {
                    $scope.loginError.username = ''
                }
            })

            var tokenExists = $cookies.get('token')
            if (tokenExists) {
                // verify token
                $scope.loggedIn = true;
                $cookies.remove('token')
                $scope.user = {
                    username: $cookies.get('username')
                }
                // window.location.reload()
            }

            // Main login handling for user
            $scope.doLogin = function(user) {
                // console.log(user)
                if (!user.username) {
                    $scope.loginError.username = ['This field may not be blank.']
                } 

                if (!user.password) {
                    $scope.loginError.password = ['This field is required.']
                }

                // If both the username and the password are supplied then POST it to the login API URL
                if (user.username && user.password) {
                    $http({
                        method: 'POST',
                        url: loginUrl, 
                        data: {
                            username: user.username,
                            password: user.password                            
                        },
                        headers: {}
                    }).then(function successCallback(r_data, r_status, r_headers, r_config) {
                        // console.log(r_data.data)
                        $cookies.put('token', r_data.data.token)
                        $cookies.put('username', r_data.data.username)
                        var token = $cookies.get('token')
                        // console.log(token)

                        $location.path('/dashboard')
                        // window.location.reload()                      
                    }, function errorCallback(e_data, e_status, e_headers, e_config) {
                        // Check if this is a 400 error which is related to an invalid password
                        if (e_data.status == 400) {
                            $scope.loginError.invalid = ['The credentials entered are invalid.']
                        }
                    })    
                } 
            }
        }
    })

然后在仪表板中,我做了以下操作:

Then for the dashboard I just did the following:

// dashboard.component.js

'use strict';

angular.module('dashboard').
    component('dashboard', {
        templateUrl: '/api/templates/dashboard.html',
        controller: function($cookies, $location, $stateParams, $rootScope, $scope) {
            var token = $cookies.get('token')
            console.log(token)
            if (token) {
                $location.path('/dashboard')
            } else {
                $location.path('/')
            }
        }
    });

我希望它能正常工作:

  • 如果您尝试访问/dashboard,它将带您进入登录屏幕
  • 如果您登录并被路由到/dashboard,则可以在URL中输入/dashboard并显示该URL
  • 如果您注销,将不允许您通过输入/dashboard或点击浏览器中的后退"按钮来查看
  • 它不允许直接访问子视图,我认为这仅是由于路由:如果父视图不能显示子视图,则无法呈现子视图.
  • if you try to go /dashboard it will route you to the login screen
  • if you login and are routed to /dashboard you can type in /dashboard to the URL and it displays it
  • if you logout, it will not allow you to view /dashboard by typing it in or hitting the back button in browser
  • it doesn't allow access to the subviews directly, which I think is just due to routing: that subviews can't be rendered if the parent view cannot.

无论如何,反馈将不胜感激.

Anyway, feedback would be greatly appreciated.

意识到这与我正在复制的项目有多相似,但我将其放置在仪表板组件中,而不是拦截器.

Realizing how similar this is to the project I am copying, but instead of an interceptor I have it in in the dashboard component.

这篇关于尝试访问受保护的页面时需要尝试登录才能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆