Django学习笔记:Authentication用户认证系统

Django认证系统的组成部分:

User(用户)

Permission(许可,定义一个用户的权限)

Group(组,分配批量用户的权限)


非Django认证系统的业务范围(需要使用第三方工具):

密码强度检查

登录请求限制

第三方认证

...



Django认证系统的配置项

在INSTALLED_APPS中:

'django.contrib.auth'                #认证框架的核心以及默认模型

'django.contrib.contenttypes'         #内容类型系统,用于给模型关联许可

(已默认添加)

在MIDDLEWARE中:

'django.contrib.sessions.middleware.SessionMiddleware'        #通过请求管理会话

'django.contrib.auth.middleware.AuthenticationMiddleware'      #将会话和用户关联

(已默认添加)

配置完成后,运行migrations命令,创建和认证系统相关的数据表。


在settings.py中:

LOGIN_URL =                             #设置认证失败的跳转页面

LOGIN_REDIRECT_URL =                    #设置登录成功的跳转页面



User模型的字段

username(必填,30)

password(必填,明文密码的hash)

email(可选)

first_name(可选,30)

last_name(可选,30)

groups(多对多)

user_permissions(多对多)

is_staff(Boolean类型,判断用户是否可以登录admin site)

is_active(Boolean类型,判断用户是否为激活状态,删除账户的时候可以将该属性设为False,而不直接删除,这样能保留引用到该用户的外键)

is_superuser(Boolean类型,判断用户是否拥有所有的许可)

last_login(datetime类型,用户最近登录时间)

date_joined(datetime类型,用户创建时间)


只有Django自带的User模型能使用认证系统功能,所以我们的用户模型直接利用或继承于Django的User模型:

from django.contrib.auth.models import User



创建用户

直接创建User实例,create_user(username, email=None, password=None):

user = User.objects.create_uer(‘<用户名>’, ‘<用户邮箱>’, ‘<密码>’)

user.is_staff = True         #此行可选,让用户有权登录admin

user.save()

#创建一个is_active=True(已激活)的实例对象,以后通过修改对象的属性来修改用户


创建超级用户

python manage.py createsuperuser


修改密码

详见Admin笔记-修改密码。

千万不能直接给User对象的password属性赋值。



用户验证和登录

用户验证:authenticate(username=None, password=None, **kwargs),该方法返回通过认证的User类对象(如果有多个对象通过认证就返回多个对象),如果没有用户通过认证或产生PermissionDenied异常,则返回None。

用户登录:login(request, user),该方法会使用SessionMiddleware把用户ID存入session中。

from django.contrib.auth import authenticate, login


def login_user(request):

    form = LoginForm(request.POST)       #表单事先写了某些验证规则,将表单实例化

    if form.is_valid():         #先用表单进行用户输入的格式验证,如果格式合法,查询数据库

        user_name = request.POST.get(‘user_name’, ‘’)

        pass_word = request.POST.get(‘pass_word’, ‘’)

        user = authenticate(username=user_name, password=pass_word)

        if user is not None:

            if user.is_active:

                login(request, user)

                return renser(request, ‘登录成功页面’)

            else:

                return render(request, ‘账户无效/密码错误页面’, {‘msg’: ‘用户名或密码错误’} )

    else:

        return renser(request, ‘输入无效页面’, {‘form’: form} )       #表单返回给用户重新输入


#前端页面的样式:{% for value in form.values %} {{ value }} {% endfor %}

                  #展示用户不规范的输入


注销当前的用户登录

from django.contrib.auth import logout


logout(request)

#即使当前用户未登录也不产生异常,logout后,用户的session数据将被清空。


匿名用户AnonymousUser

用户未登录的时候,request.user属性值就是匿名用户AnonymousUser的实例,匿名用户的特点:

id = None

is_anoymous()为True

is_authenticated()为False


判断某用户是否登录

每一次用户请求中都包含一个request.user属性,判断方法:

if request.user.is_authenticated():

    #用户已登录的操作...

else:

    #用户未登录的操作...

注意,Django 1.11使用is_authenticated(),Django 2.0使用is_authenticated


用装饰器限制用户权限

@login_required(redirect_field_name=next, login_url=settings.LOGIN_URL)

redirect_field_name:定义登录成功后跳转到之前访问的url

login_url:指定登录界面的url

如果用户登录,执行被装饰的views视图;如果用户未登录,将重定向到settings.LOGIN_URL,并传递当前的url到请求参数中,如/accounts/login/?next=/xxx/。


from django.contrib.auth.decorators import login_required


@login_required

def some_view(request):

    # ...


自定义authenticat方法

在views.py中编写类:

from django.contrib.auth.backends import ModelBackend


class CustomBackend(ModelBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):

        #自定义的认证逻辑...


在settings.py中注册:

AUTHENTICATION_BACKENDS = (

    ‘<CustomBackend的引用路径>’,

)


用UserProfile储存用户的额外信息

①定义UserProfile模型:

from django.contrib.auth.models import user


class UserProfile(models.Model):

    user = models.OneToOneField(User)       #创建和User的一对一关系

    #额外的属性...


②在settings.py中:

AUTH_PROFILE_MODULE = ‘<应用名>.<UserProfile>’


此时,User对象的get_profile()方法就会返回对应的UserProfile对象。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容