Django rest framework 身份和权限验证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django rest framework 身份和权限验证相关的知识,希望对你有一定的参考价值。

参考技术A 认证成功提供以下信息
request.user 将是一个 Django User 实例。
request.auth 将是 None

a. 设置在 setting.py 的 INSTALLED_APPS 中添加 rest_framework.authtoken
b. 执行 manage.py migrate 生成 token 相关的表

如何生效请看 三

a. 修改 .authenticate(self, request) 方法完成自定义验证

该方法返回 (user, auth) 元组或 None

b. 修改 .authenticate_header(self, request)

如果实现该方法,则应返回一个字符串,该字符串将用作 HTTP 401 Unauthorize 响应中的 WWW-Authenticate 头的值

如果 .authenticate_header() 方法未被重写,则认证方案将在未验证的请求被拒绝访问时返回 HTTP 403 Forbidden 响应

示例

a. 重写 .has_permission(self, request, view)

b. 重写 .has_object_permission(self, request, view, obj)

区别:
has_permission 在请求进来的时候就开始了属于DRF的三大认证,返回 True 就能访问, False 就禁止访问
has_object_permissions 是对某个对象的访问权限,

如果请求被授予访问权限,方法应该返回True,否则返回False。

: 仅当视图级 has_permission 检查已通过时,才会调用实例级 has_object_permission 方法

未提供 Django Rest Framework 身份验证凭据

【中文标题】未提供 Django Rest Framework 身份验证凭据【英文标题】:Django Rest Framework Authentication credentials were not provided 【发布时间】:2015-05-16 14:08:09 【问题描述】:

我在 DRF 和 Angularjs 上使用 django-rest-authdjango-all-auth。在任何有关身份验证的请求中,我都会收到以下错误:

"detail":"Authentication credentials were not provided."

通过SO,我意识到有很多类似的问题,因此将它们累积在一起,我尝试了以下方法:

settings.py

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    ...
    'rest_framework',
    'rest_framework.authtoken',
    'rest_auth',
    ...
    'allauth',
    'allauth.account',
    'rest_auth.registration',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',

)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

DEFAULT_AUTHENTICATION = 
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.OAuth2Authentication',
        'rest_framework.authentication.TokenAuthentication',
    ),

REST_FRAMEWORK = 
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser'
   ),

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend"
)
TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.request",
    "django.contrib.auth.context_processors.auth",
    "allauth.account.context_processors.account",
    "allauth.socialaccount.context_processors.socialaccount",
)

REST_SESSION_LOGIN = False

我的app.js 文件

sgApp.config(['$routeProvider','$locationProvider', '$httpProvider',
    function($routeProvider, $locationProvider, $httpProvider)
        $routeProvider.when('/',
            templateUrl: '/static/partials/index.html',
            controller: 'indexCtrl'
        ).when('/abc',
            templateUrl: 'static/partials/index.html'
        ).otherwise(
            redirectTo: '/'
        );
        $locationProvider.html5Mode(true).hashPrefix('!');
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    
]).controller('someCtrl', function($scope, $http, $httpProvider)
       $scope.login = function() 
           Facebook.login(function(response) 
            var postDict = 
                access_token: response.authResponse.accessToken
            
            $http.post('/sgAuth/facebook/', postDict).
                success(function(data)
                    $httpProvider.defaults.headers.common.Authorization = 'Token ' + data.key;
                    $scope.loggedIn = true;
                    $scope.userDetails(); //function that gets user details
                );
        );
    ;
);

我哪里错了?

【问题讨论】:

登录有效吗?如果您将data.token 登录到控制台,您能看到它吗?如果您查看浏览器的开发人员工具 (F12),请求中是否出现 Token 标头? @KevinBrown,这是非常随意的。它有时会起作用,但不会注销。如果它确实注销,我将无法再次登录。 只是为了解决这个问题,我会尝试在您调用自己的 API 登录之前添加一个 console.log(response.authResponse.accessToken) 。我还将确保您的令牌按照 Kevin Brown 的建议正确填充。如果 FB 工作正常但您的令牌丢失,那么您需要检查您的日志。 我也有同样的问题。 @ItaloMaia,嘿,你遇到了什么问题?我修复了它,所以我也许可以帮助你。 【参考方案1】:

您的设置中有权限等级:

REST_FRAMEWORK = 
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser'
   ),

所以只有管理员用户提出的请求才会通过。

【讨论】:

【参考方案2】:

我在您的线路中遇到了同样的问题:

$httpProvider.defaults.headers.common.Authorization = 'Token' + data.key;

试试这个:

httpProvider.defaults.headers.common.Authorization = 'JWT' + data.key;

问候。

【讨论】:

以上是关于Django rest framework 身份和权限验证的主要内容,如果未能解决你的问题,请参考以下文章

在 django-rest-framework 中,是不是可以同时使用 oauth 和 session 身份验证?

Django Rest Framework 中的 JWT 身份验证错误“无效签名”

缺少 Django、React 和 Rest Framework JWT 身份验证标头

Django REST Framework - API 身份验证 - 授权应用程序而不是用户

django rest framework jwt 使用电子邮件和密码进行身份验证

使用 Django REST Framework 进行身份验证返回 405