ANDROID VOLLEY + JWT TOKEN 认证 + DJANGO REST 框架
Posted
技术标签:
【中文标题】ANDROID VOLLEY + JWT TOKEN 认证 + DJANGO REST 框架【英文标题】:ANDROID VOLLEY + JWT TOKEN AUTHENTICATION + DJANGO REST FRAMEWORK 【发布时间】:2020-10-21 23:45:11 【问题描述】:我目前正在开发一个安卓聊天应用程序。我对 android Studio、JWT 令牌授权和 Django Rest 框架非常陌生。现在我在 Django 方面遇到问题。
所以基本上我是在我的 Android 上设置一个登录页面,我希望它使用电话号码和密码作为所需的凭据登录。不过,我也想使用 JWT Token Auth 来让我的应用更安全。
目前我的项目 urls.py 指向 JWT Token API 之一
urls.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
的模型models.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
目前我已经尝试对我的模型进行很多修改,例如:
更改用户名 = 无 REQUIRED_FIELDS = [] USERNAME_FIELDS = 'phone_number'我意识到令牌获取对视图在您需要的信息(用户名和密码)方面遵循 Django 管理页面。
但是,当我修改时,我尝试创建超级用户并尝试使用我修改后的数据登录 Django Admin。但我仍然无法登录。另外,我尝试从我创建的超级用户那里获取令牌,但是它将以“详细信息”响应:“未找到具有给定凭据的活动帐户”
有人可以告诉我我现在应该采取的步骤吗?我试图寻找解决方案,但没有一个能解决我的问题
这是 TLDR 的重点:
-
我希望我的应用使用电话号码和密码登录,并希望使用 JWT Token Auth 来确保其安全。
我意识到ObtainTokenPair 视图遵循Django Admin 凭据,因此我尝试将我的后端修改为使用电话号码和密码“登录”。
修改后,我无法登录 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)
【问题讨论】:
对不起,*** 的新手@jps 【参考方案1】:如果不亲身参与实际项目,很难确定错误。我找不到错误或修复您的项目。你必须自己做。但我肯定可以分享我认为可以帮助您避免错误并修复您的项目的内容。
我能理解的
-
您需要自定义用户模型
您想使用 jwt 身份验证
那么,让我们开始吧。用户模型和身份验证是两个不同的东西。首先创建自定义用户模型。
首先,从数据库中删除所有用户
完全按照这个“A full example”创建自定义用户模型(通过创建超级用户检查自定义用户模型是否正常工作,如果不是这意味着你错过了一些东西,请重试)
如果您已成功创建自定义用户模型,这意味着您现在已将“用户名”替换为“电话号码”(在您的情况下)
对于身份验证,您可以使用自定义身份验证,或者您可以使用现有的包。将其配置为默认身份验证后端。
您选择的身份验证包应采用用户名和密码,检查是否有用户匹配这些凭据创建一个令牌并返回该令牌。您不需要修改您只需提供用户名字段(电话号码)和密码的身份验证过程。现在在这里你可能需要做类似的事情
username: phone_number, password: password
因为您的身份验证包可能不支持自定义用户。 希望有帮助。
【讨论】:
哇,非常感谢老兄...会尝试你的建议 嘿伙计,您的链接没有提供自定义用户模型的教程,而只是 JWT @mursalin 的文档 @Heinrich 确实如此,请查看标题为“完整示例”的页面末尾的示例。在那里您可以找到自定义用户模型的完整示例。 哦,抱歉没看到……非常感谢@mursalin……无论如何,关于身份验证是不是关于覆盖 AUTHENTICATION_BACKENDS ?? @Heinrich,这取决于您使用的软件包。如果您不使用此软件包,请检查此django-rest-framework-simplejwt.readthedocs.io/en/latest/…,没问题只需查找有关您的软件包的文档。以上是关于ANDROID VOLLEY + JWT TOKEN 认证 + DJANGO REST 框架的主要内容,如果未能解决你的问题,请参考以下文章
NullPointerException:尝试从字段 'com.android.volley.Cache$Entry com.android.volley.Response.cacheEntry 读取
[转] Android Volley完全解析,初识Volley的基本用法