咱們用 Django
和 rest-framework
開發用戶模塊, 並使用 JWT(Json Web Token)
進行用戶認證, 該項目將上傳在 MedusaSorcerer/django-restframework-demo 上供你們借鑑和使用。python
開發環境:Windows10
開發 IDE:Pycharm
開發框架:Django
開發語言:Pythonmysql
python==3.8.2
django==3.0.6
django-restframework
django-restframesork-jwt
複製代碼
在 CMD
命令行界面, 建立 Django
項目程序 Medusa
:git
python3 -m django startproject Medusa
複製代碼
在 Medusa
根目錄下建立應用總模塊 applications
:github
cd Medusa
mkdir applications
複製代碼
進入 applications
建立應用模塊 User
, 這兒採用傻瓜式操做, 建立層級 Django-APP
:sql
cd applications
python3 ../manage.py startapp User
複製代碼
此時項目結構以下: shell
修改 applications/User/apps.py
:數據庫
from django.apps import AppConfig
class UserConfig(AppConfig):
name = 'applications.User'
複製代碼
在項目根目錄新建配置文件夾 config
, 並添加配置文件 config.py
:django
cd ..
mkdir config
cd config
type NUL > config.py
複製代碼
在 config/config.py
新增如下配置內容:json
#!/usr/bin/env python
# _*_ Coding: UTF_8 _*_
# MySQL 服務地址
MYSQL_SERVER_HOST = '127.0.0.1'
# MySQL 服務端口
MYSQL_SERVER_PORT = '3306'
# MySQL 數據庫名稱
MYSQL_DATABASE_NAME = 'medusa'
# MySQL 數據庫鏈接用戶帳號
MYSQL_SERVER_USERNAME = 'root'
# MySQL 數據庫鏈接用戶密碼
MYSQL_SERVER_PASSWORD = 'mysql-password'
複製代碼
修改 Medusa/settings.py
中配置參數 ALLOWED_HOSTS
:api
ALLOWED_HOSTS = ['*']
複製代碼
添加 Medusa/settings.py
中應用註冊參數 INSTALLED_APPS
:
INSTALLED_APPS = [
...,
'applications.User',
]
複製代碼
在 Medusa/settings.py
頂部導入配置文件:
from config import config
複製代碼
在 Medusa/setting.py
中修改配置數據庫參數 DATABASES
:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': config.MYSQL_DATABASE_NAME,
'USER': config.MYSQL_SERVER_USERNAME,
'PASSWORD': config.MYSQL_SERVER_PASSWORD,
'HOST': config.MYSQL_SERVER_HOST,
'PORT': config.MYSQL_SERVER_PORT,
}
}
複製代碼
在 Medusa/setting.py
中修改配置時區參數 TIME_ZONE
:
TIME_ZONE = 'Asia/Shanghai'
複製代碼
固然你能夠繼續在 Medusa/settings.py
修改語言參數, 咱們建立的項目暫不修改:
LANGUAGE_CODE = 'zh-hans'
複製代碼
確保你的 MySQL
中已經存在了你配置的數據庫名稱對應的數據庫, 而且能夠鏈接成功, 就能夠嘗試在 Medusa
根目錄下啓動 Django
項目,:
python3 manage.py runserver 0.0.0.0:8000
複製代碼
你若是執行成功你能夠訪問 http://127.0.0.1:8000/ 就看到如下界面:
在 applications/User/models.py
中自定義咱們的用戶模型類
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
class Meta:
db_table = 'medusa_user'
ordering = ('-id',)
複製代碼
咱們採用的是繼承 AbstractUser
類並指定 db_table
的方式, 此時你可使用 Pycharm
的 Ctrl + B
進入父類中查看 User
具備的屬性和方法。
固然了, 在執行到這個步驟的時候其實用戶的模型類並無生效, 而須要達到生效的效果則是須要指定用戶模型類的位置參數, 你只須要在 Medusa/settings.py
中用 AppName.UserModelsName
的方式指定用戶模型類便可:
AUTH_USER_MODEL = 'User.User'
複製代碼
有關於用戶認證的模型類介紹, 推薦你查閱 Customizing authentication in Django。
使用 Django 遷移命令遷移數據庫生成數據表:
python3 manage.py makemigrations
python3 manage.py migrate
複製代碼
你可使用 MySQL
數據庫鏈接應用查看你生成的數據表。
在準備好基本環境後咱們進行登陸接口的開發工做, 登陸的接口主要是對用戶進行驗證以及口令的返回, 使用 JWT
驗證的時候先安裝導入須要的包應用 rest_framework
, 添加 Medusa/settings.py
中應用註冊參數 INSTALLED_APPS
:
INSTALLED_APPS = [
...,
'rest_framework',
]
複製代碼
在 applications/User/
下建立用戶認證的視圖文件 userauth.py
並撰寫用戶登陸認證視圖類:
#!/usr/bin/env python
# _*_ Coding: UTF-8 _*_
from rest_framework_jwt.serializers import JSONWebTokenSerializer
from rest_framework_jwt.views import JSONWebTokenAPIView
class UserLoginAPIView(JSONWebTokenAPIView):
serializer_class = JSONWebTokenSerializer
複製代碼
簡簡單單的幾行代碼就實現了一個用戶登陸的接口, 你如今就須要在你的路由管理器裏面註冊這個登陸的 API 試圖便可, 在 Medusa/urls.py
中 urlpatterns
參數中註冊路由:
urlpatterns = [
path('api/v1.0.0/user/login', userauth.UserLoginAPIView.as_view())
]
複製代碼
不要着急, 咱們是否是尚未建立用戶呢?
python3 manage.py createsuperuser
複製代碼
依次輸入:
由於我輸入的密碼是 admin
, 因此在建立的時候給了三個警告信息, 須要你確認信息後再次確認:
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
This password is too common.
複製代碼
無論他, 上去就是一個 y
給他:
對於已經登陸的用戶實現登出功能, 主要的是在於登陸的一種身份判斷, 那等同於一個惟一字段能實現判斷登陸用戶登出後變化, 而且從新生成這個惟一字段。
咱們在 User
類中加入這樣一條字段配置:
from uuid import uuid4
user_secret = models.UUIDField(default=uuid4())
複製代碼
注意 user_secret
是 User
類的一個屬性, 你可能會想那我是否是要從新實現喲用戶登陸的邏輯呢? 答案是不須要的, 由於咱們建立的字段, 咱們用函數路徑的方式指定原先的函數, 咱們將採用重寫本來的判斷函數便可實現:
在項目根目錄下的 applications/User/views.py
中建立函數, 函數位置可自行肯定, 你也能夠建立一個 .py
文件:
#!/usr/bin/env python
# _*_ Coding: UTF-8 _*_
def get_user_secret(user):
return user.user_secret
複製代碼
主要的內容是在 Medusa/settings.py
中配置函數路徑:
JWT_AUTH = {
'JWT_GET_USER_SECRET_KEY': 'applications.User.views.get_user_secret'
}
複製代碼
由於咱們修改了模型類, 因此咱們須要對數據庫進行再次遷移:
python3 manage.py makemigrations
python3 manage.py migrate
複製代碼
在 applications/User/userauth.py
中建立登出視圖:
import uuid
from rest_framework import status, views
from rest_framework.response import Response
class UserLogoutAPIView(views.APIView):
def get(self, request, *args, **kwargs):
user = request.user
user.user_secret = uuid.uuid4()
user.save()
return Response({'detail': 'login out.', 'status': status.HTTP_200_OK}, status=status.HTTP_200_OK)
複製代碼
在路由模塊 Medusa/urls.py
中註冊:
urlpatterns = [
... ,
path('api/v1.0.0/user/logout', userauth.UserLogoutAPIView.as_view()),
]
複製代碼
測試一下:
NotImplementedError: Django doesn't provide a DB representation for AnonymousUser.
複製代碼
What? 報錯了, 由於咱們訪問 API 的時候沒有使用認證信息, 因此訪問的 User 對象是一個匿名用戶對象, 因此咱們須要對這個接口採起認證:
from rest_framework.permissions import IsAuthenticated
class UserLogoutAPIView(views.APIView):
permission_classes = [IsAuthenticated]
def get(self, request, *args, **kwargs):
...
複製代碼
添加認證參數 permission_classes
表示須要 IsAuthenticated
已認證的對象才能夠訪問, 再次嘗試接口會收到如下 json
提示:
{
"detail": "Authentication credentials were not provided."
}
複製代碼
認證失敗? 咱們在 Medusa/settings.py
中添加如下配置信息:
import datetime
JWT_AUTH = {
# 以前配置的用戶依據判斷函數路由
'JWT_GET_USER_SECRET_KEY': 'applications.User.views.get_user_secret',
# 用戶認證數據的過時時間
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1)
}
REST_FRAMEWORK = {
# 用戶認證類
'DEFAULT_AUTHENTICATION_CLASSES': (
# 優先使用 JWT 的方式認證用戶
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
複製代碼
{
"detail": "login out.",
"status": 200
}
複製代碼
在建立用戶的時候咱們不會使用命令行來建立用戶的, 使用模型類的時候建立用戶通常會這樣來實現, 固然了, 這兒咱們省略了一些操做, 僅僅介紹建立用戶的快捷方式:
from applications.User.models import User
User.objects.create_user(username=username, email=email, password=password, **extra_fields)
User.objects.create_superuser(username=username, email=email, password=password, **extra_fields)
複製代碼
後面攜帶的 **extra_fields
可讓你攜帶更多的 Models 指定的字段, 若是你須要的話。
該描述內容有些省略的地方或者描述不清的地方請留言
代碼已經同步至 Github 地址:MedusaSorcerer/django-restframework-demo 今天你進步了嗎?