码迷,mamicode.com
首页 > 其他好文 > 详细

Django-cas-ng没有跳转到预想的地址,报错Not Found: /accounts/login/

时间:2020-12-19 12:11:59      阅读:1      评论:0      收藏:0      [点我收藏+]

标签:解决   否则   port   for   cal   ini   shel   callback   dispatch   

Django-cas-ng 报Not Found: /accounts/login/

报错如下,在请求接口地址时,由于未登录,会跳转到登录页面,但是没有往预想的登录页跳转,而是跳转到/accounts/login/

[14/Dec/2020 14:17:55] "GET /api/v1/project/ HTTP/1.1" 302 0
Not Found: /accounts/login/
[14/Dec/2020 14:17:55] "GET /accounts/login/?next=/api/v1/project/ HTTP/1.1" 404 2221

在使用了django-cas-ng后,访问自定义的路由地址时,总发现跳转的登录地址不正确,浏览器地址也会跳转到/accounts/login,b并非跳转到配置的cas登录地址。

项目目录结构如下:

├─AuthService

│ │ apps.py

│ │ get_token.py

│ │ models.py

│ │ authentication.py

│ │ urls.py

│ │ init.py



├─demo1

│ │ admin.py

│ │ apps.py

│ │ models.py

│ │ serializer.py

│ │ urls.py

│ │ views.py

│ │ init.py

├─ProjectName

│ │ asgi.py

│ │ settings.py

│ │ urls.py

│ │ wsgi.py

│ │ init.py

AuthService是我用来控制登录,认证,鉴权的模块.所以把cas登录的路由地址也写在这里了

AuthService/urls.py

from django.urls import path
import django_cas_ng.views


urlpatterns = [
    path(‘login/‘, django_cas_ng.views.LoginView.as_view(), name=‘cas_ng_login‘),
    path(‘logout/‘, django_cas_ng.views.LogoutView.as_view(), name=‘cas_ng_logout‘),
    path(‘callback/‘, django_cas_ng.views.CallbackView.as_view(), name=‘cas_ng_callback‘),
]

ProjectName/urls.py(你的项目settings.py文件所在的项目目录)

from django.contrib import admin
from django.urls import path
from django.urls import include

urlpatterns = [
    path(‘admin/‘, admin.site.urls),
    path(‘auth/‘, include(‘AuthService.urls‘)),
    path(‘api/‘, include(‘demo1.urls‘)),
]

请求地址http://127.0.0.1:8000/api/v1/project/

浏览器地址跳转如下:http://127.0.0.1:8000/accounts/login/?next=/api/v1/project/

可以看到,地址跳转到/accounts/login路由,并没有跳转到/auth/login/,只有跳转到/auth/login/才会跳转到cas服务器的登录地址,所以此时并不会跳转到cas服务的登录地址。

demo1/views.py

# 鉴权
@method_decorator(login_required, name=‘dispatch‘)
class ProjectV1APIView(generics.RetrieveAPIView,
                       generics.ListAPIView,
                       generics.CreateAPIView,
                       generics.UpdateAPIView,
                       generics.DestroyAPIView):
    # 极其简单的鉴权,根据请求用户判断是否是超管,是则可以访问,否则不能访问
    permission_classes = [IsSuperUser]
    queryset = ProjectsInfo.objects.all().order_by(‘id‘)
    serializer_class = ProjectsInfoSerializer

    def get(self, request, *args, **kwargs):
        if ‘pk‘ in kwargs:
            return self.retrieve(request, *args, **kwargs)
        else:
            return self.list(request, *args, **kwargs)

就是这里,由于未登录,用户为匿名用户,所以跳转到登录页,也就是login_requied这里拦截做了跳转,然后查看login_required方法

def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
    """
    Decorator for views that checks that the user is logged in, redirecting
    to the log-in page if necessary.
    """
    actual_decorator = user_passes_test(
        lambda u: u.is_authenticated,
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

可以看到源码中有login_url,顾名思义,也就是登录的地址,选中login_url,ctrl+b跳转到声明:

def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    Decorator for views that checks that the user passes the given test,
    redirecting to the log-in page if necessary. The test should be a callable
    that takes the user object and returns True if the user passes.
    """

    def decorator(view_func):
        @wraps(view_func)
        def _wrapped_view(request, *args, **kwargs):
            if test_func(request.user):
                return view_func(request, *args, **kwargs)
            path = request.build_absolute_uri()
            resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
            # If the login url is the same scheme and net location then just
            # use the path as the "next" url.
            login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
            current_scheme, current_netloc = urlparse(path)[:2]
            if ((not login_scheme or login_scheme == current_scheme) and
                    (not login_netloc or login_netloc == current_netloc)):
                path = request.get_full_path()
            from django.contrib.auth.views import redirect_to_login
            return redirect_to_login(
                path, resolved_login_url, redirect_field_name)
        return _wrapped_view
    return decorator

这么一行代码resolved_login_url = resolve_url(login_url or settings.LOGIN_URL),可以看到解析登录url时是接收参数或者从url.settings文件中读取LOGIN_URL。查看了下自己的settings.py,果然没有配置LOGIN_URL,再搜索了下DJANGO LOGIN_URL,默认刚好是/accounts/login/,那么问题就找到了,原来是LOGIN_URL没有配置,默认到/accounts/login/路由地址了,导致没有跳转到预期的cas登录地址。
解决方法,在setting.py中加一行配置:

LOGING_URL = ‘/auth/login‘ #你的cas登录路由地址

重新运行,访问原来的接口地址,发现可以跳转到正确的cas服务登录地址了。

Django-cas-ng没有跳转到预想的地址,报错Not Found: /accounts/login/

标签:解决   否则   port   for   cal   ini   shel   callback   dispatch   

原文地址:https://www.cnblogs.com/fuyouduhai/p/14133805.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!