首页 > 解决方案 > ANDROID VOLLEY + JWT TOKEN 认证 + DJANGO REST 框架

问题描述

我目前正在开发一个安卓聊天应用程序。我对 Android Studio、JWT 令牌授权和 Django Rest 框架非常陌生。现在我在 Django 方面工作有问题。

所以基本上我是在我的 Android 上设置一个登录页面,我希望它使用电话号码和密码作为所需的凭据登录。但是,我也想使用 JWT Token Auth 来使我的应用程序更安全。

目前我的项目urls.py指向 JWT Token API 之一

网址.py

from django.contrib import admin
from django.urls import path,include
from django.conf.urls import include, url
from rest_framework_simplejwt import views as jwt_views



urlpatterns = [
    path('admin/', admin.site.urls),
    path('account/',include('restaccount.urls')) ,
    path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
]   

这将导致服务器页面是 在此处输入图像描述

*PS:电话号码字段应该是默认的用户名字段..(我在发布之前对我的代码进行了一些尝试修改)。

我还设置了一个继承自AbstractUser的模型

模型.py

class RegisterUser(AbstractUser):
    phone_number = PhoneField(name='phone_number',unique=True)
    birthday = models.DateField(name ='birthday',null= True)
    nickname = models.CharField(max_length=100,name = 'nickname')

    def __str__(self):
        return self.phone_number

目前我已经尝试对我的模型进行很多修改,例如:

我意识到令牌获取对视图在您需要的信息(用户名和密码)方面遵循 Django 管理页面。

但是,当我修改时,我尝试创建超级用户并尝试使用修改后的数据登录 Django Admin。但我仍然无法登录。另外,我尝试从我制作的超级用户那里获取令牌,但它会响应在“详细信息”中:“未找到具有给定凭据的活动帐户”

有人可以告诉我我现在应该采取的步骤吗?我试图寻找解决方案,但没有一个能解决我的问题

这是 TLDR 的重点:

  1. 我希望我的应用程序使用电话号码和密码登录,并希望使用 JWT Token Auth 来确保它的安全。
  2. 我意识到ObtainTokenPair 视图遵循Django Admin 凭据,因此我尝试将我的后端修改为使用电话号码和密码“登录”。
  3. 修改后,我无法登录 Django Admin,也无法使用我创建的超级用户获取令牌。

这里附上一些相关文件: Settings.py

"""
Django settings for androidapp project.

Generated by 'django-admin startproject' using Django 3.0.7.

For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '6qdk058^8b2@-pnw!cr1pbd(sao)vj+v69&4874zjh95xu7pg)'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['172.31.120.211',]


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'rest_framework',

    'restaccount',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'androidapp.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'androidapp.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'Orbital',
        'USER' :'SomeUser',
        'PASSWORD':'Pass',
        'HOST' : 'localhost',
        'PORT' : '',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = False

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

AUTH_USER_MODEL = 'restaccount.RegisterUser'


#FORMAT FOR DATE INPUT  
DATE_INPUT_FORMATS = ('%d-%m-%Y', '%d/%m/%Y', '%d/%m/%y', '%d %b %Y',
                      '%d %b, %Y', '%d %b %Y', '%d %b, %Y', '%d %B, %Y',
                      '%d %B %Y')

#Format for date-time input format   
DATETIME_INPUT_FORMATS = ('%d/%m/%Y %H:%M:%S', '%d/%m/%Y %H:%M', '%d/%m/%Y',
                          '%d/%m/%y %H:%M:%S', '%d/%m/%y %H:%M', '%d/%m/%y',
                          '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d')

# Adding REST_FRAMEWORK SETTING WITH JWT AUTHENTICATION
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
}

# AUTHENTICATION_BACKENDS = (
#     'django.contrib.auth.backends.ModelBackend',
#     'restaccount.backends.UserBackend'
# )

在 models.py 中注册用户管理器

class RegisterUserManager(BaseUserManager):

    def create_user(self, phone_number,password, **extra_fields):
        if not phone_number:
            raise ValueError('The phone number must be set')

        user = self.model(
            phone_number=phone_number,
            password = password,
            **extra_fields)

        user.save()
       
        return user
        
    def create_superuser(self,phone_number,password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        # print(phone_number)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))

        return self.create_user(phone_number, password,**extra_fields)

标签: androiddjangodjango-rest-frameworkandroid-volleyjwt-auth

解决方案


如果不亲身参与实际项目,很难确定错误。我找不到错误或修复您的项目。你必须自己做。但是我可以肯定地分享我认为可以帮助您避免错误并修复您的项目的内容。

我能理解的

  1. 你想要一个自定义的用户模型
  2. 您想使用 jwt 身份验证

那么,让我们开始吧。用户模型和身份验证是两个不同的东西。首先创建自定义用户模型。

  1. 首先,从数据库中删除所有用户

  2. 完全按照这个“完整示例”创建自定义用户模型(通过创建超级用户检查自定义用户模型是否正常工作,如果不是这意味着你错过了一些东西再试一次)

  3. 如果您已成功创建自定义用户模型,则意味着您现在已将“用户名”替换为“电话号码”(在您的情况下)

  4. 对于身份验证,您可以使用自定义身份验证,或者您可以尝试使用现有包。将其配置为默认身份验证后端。

  5. 您选择的身份验证包应该采用用户名和密码,检查是否有用户匹配这些凭据创建一个令牌并返回该令牌。您无需修改​​身份验证过程,只需提供用户名字段(电话号码)和密码。现在在这里你可能需要做类似的事情

    {username: phone_number, password: password}

因为您的身份验证包可能不支持自定义用户。希望能帮助到你。


推荐阅读