后端实现登陆认证
Django默认已经提供了认证系统Auth模块。
认证系统包含:
- 用户管理
- 权限管理[RBAC]
- 用户组管理(就是权限里面的角色)
- 密码哈希系统(就是密码加密和验证密码)
- 用户登录或内容显示的表单和视图
- 一个可插拔的后台系统(admin站点)
Django默认用户的认证机制依赖Session机制,但是session认证机制在前后端分离项目中具有一定的局限性。
- session默认会把 session_id 作为cookie保存到客户端,但有些客户端是默认禁用cookie或者没法使用cookie的。
- session的数据默认是保存到服务端的,带来一定的存储要求。
基于session的现有困境,我们一般在前后端分离的项目中,引入JWT认证机制来实现用户的登录和鉴权(鉴别身份,识别权限)。
jwt可以将用户的身份凭据存放在一个Token(认证令牌,本质上就是一个经过处理的字符串)中,
然后把token发送给客户端,客户端可以选择采用自己的技术来保存这个token。
cookie、session和token都是用于身份验证的机制,但它们的实现方式和存储位置不同。
Cookie是存储在浏览器中的小文本文件,它们可以用于维持用户的会话状态,但是它们容易被黑客窃取。
Session数据是存在服务器中的,相对于Cookie来说更安全,但是Session数据是保存在服务器上的,如果服务器被攻击,那么Session数据也会被窃取。
Token是一种更加安全的机制,它们可以用于维持用户的会话状态,并且可以在客户端和服务器之间进行加密传输。
Token还可以用于授权,以便用户可以访问他们没有权限访问的资源。
Token一般放在客户端的存储中,例如localStorage、sessionStorage或cookie中。每次调用接口的时候,它会作为字段传给后台。
在django中如果要实现jwt认证,有一个常用的第三方jwt模块,我们可以很方便的去通过jwt对接Django的认证系统,帮助我们来快速实现:
- 用户的数据模型
- 用户密码的加密与验证
- 用户的权限系统
01. Django用户模型类
from django.contrib.auth.models import User
Django的Auth认证系统中提供了用户模型类User保存用户的数据,默认的User包含以下常见的基本字段:
字段名 | 字段描述 |
---|---|
username | 必选。150个字符以内。 用户名可能包含字母数字,_ ,@ ,+ . 和- 个字符。 |
first_name | 可选(blank=True )。 少于等于30个字符。 |
last_name | 可选(blank=True )。 少于等于30个字符。 |
email | 可选(blank=True )。 邮箱地址。 |
password | 必选。 密码的哈希加密串。(Django 不保存原始密码)。原始密码可以无限长而且可以包含任意字符。 |
groups | 与Group 之间的多对多关系。对接权限功能的。 |
user_permissions | 与Permission 之间的多对多关系。对接权限功能的。 |
is_staff | 布尔值。 设置用户是否可以访问 Admin 站点。 |
is_active | 布尔值。 指示用户的账号是否激活。 它不是用来控制用户是否能够登录,而是描述一种帐号的使用状态。值为False的时候,是无法登录的。 |
is_superuser | 是否是超级用户。超级用户具有所有权限。 |
last_login | 用户最后一次登录的时间。 |
date_joined | 账户创建的时间。 当账号创建时,默认设置为当前的date/time。 |
1.1 模型提供的常用方法
模型常用方法可以通过user实例对象.方法名
来进行调用。
-
set_password
(raw_password)设置用户的密码为给定的原始字符串,并负责密码的哈希加密。 不会保存
User
对象。当None
为raw_password
时,密码将设置为一个不可用的密码。 -
check_password
(raw_password)如果给定的raw_password是用户的真实密码,则返回True,可以在校验用户密码时使用。
1.2 管理器的常用方法
管理器方法可以通过User.objects.
进行调用。
-
create_user
(username, email=None, password=None, **extra_fields)创建、保存并返回一个
User
对象。 -
create_superuser
(username, email, password, **extra_fields)与
create_user()
相同,但是设置is_staff
和is_superuser
为True
。
上面的User模型看起来已经包含很多的属性和方法了,
但实际开发中,我们往往还是需要自己添加一些字段。
比如当前我们要实现的项目是一个在线教育商城,我们还需要记录用户的手机号,或者头像等信息。
所以我们需要在原有模型的基础上对这个模型进行改造。
下面我们自定义一个新的users子应用,并在django原有功能的基础上,完善用户的登录注册功能。
02. 扩展Django用户模型类
2.1 创建用户模块的子应用
cd fuguang_api/apps/
python ../../manage.py startapp users
在settings/dev.py文件中注册子应用。
INSTALLED_APPS = [
...
'users',
]
创建users/urls.py子路由并在总路由中进行注册。
users/urls.py,代码:
from django.urls import path
from . import views
urlpatterns = [
]
fuguang_api/urls.py,总路由,代码:
from django.contrib import admin
from django.urls import path,re_path,include
from django.conf import settings
from django.views.static import serve # 静态文件代理访问模块
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'uploads/(?P<path>.*)', serve, {"document_root": settings.MEDIA_ROOT}),
path("", include("home.urls")),
path("users/", include("users.urls")),
]
2.2 创建自定义的用户模型类
Django提供了django.contrib.auth.models.AbstractUser
用户抽象模型类,允许我们继承、扩展用户认证模型类的字段。
在创建好的应用models.py中定义用户的用户模型类。
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
mobile = models.CharField(max_length=15, unique=True, verbose_name='手机号')
money = models.DecimalField(max_digits=9, default=0.0, decimal_places=2, verbose_name="钱包余额")
credit = models.IntegerField(default=0, verbose_name="积分")
avatar = models.ImageField(upload_to="avatar/%Y", null=True, default="", verbose_name="个人头像")
nickname = models.CharField(max_length=50, default="", null=True, verbose_name="用户昵称")
class Meta:
db_table = 'fg_users'
verbose_name = '用户信息'
verbose_name_plural = verbose_name
我们自定义的用户模型类还不能直接被Django的认证系统所识别,需要在配置文件中告知Django认证系统使用我们自定义的模型类。
在settings/dev.py配置文件中进行设置
AUTH_USER_MODEL = 'users.User'
AUTH_USER_MODEL
参数的设置以点.
来分隔,表示应用名.模型类名
。
注意:Django建议我们对于AUTH_USER_MODEL参数的设置一定要在第一次数据库迁移之前就设置好,否则将会与已有的迁移记录产生冲突。
这表示目前数据库已经设置了默认的子应用为users
的模型了,且有一个叫admin的子应用使用了原来的废弃的auth.User模型,所以产生了冲突。
我们需要重置下原来的auth模块的迁移操作。
解决步骤:
- 备份数据库[如果刚开始开发,无需备份。]
cd /home/moluo/Desktop/fuguang/docs mysqldump -uroot -p123 fuguang> 03_20_fuguang.sql
- 注释掉users.User代码以及AUTH_USER_MODEL配置项,然后执行数据迁移回滚操作,把冲突的所有表迁移记录全部归零
cd ~/Desktop/luffycity/luffycityapi # python manage.py migrate <子应用目录> zero python manage.py migrate auth zero
- 恢复users.User代码以及AUTH_USER_MODEL配置项,执行数据迁移。
python manage.py makemigrations python manage.py migrate
- 创建管理员,查看auth功能是否能正常使用。
python manage.py createsuperuser