Django社交网络

使用Django认证(authentication)框架

Django拥有一个内置的认证(authentication)框架用来操作用户认证(authentication),会话(sessions),权限(permissions)以及用户组。

这个认证(authentication)系统包含了一些普通用户操作视图(views),例如:登录,登出,修改密码以及重置密码。


这个认证(authentication)系统还包含了以下模型(models):

User:一个包含了基础字段的用户模型(model);这个模型(model)的主要字段有:username, password, email, first_name, last_name, is_active。

Group:一个组模型(model)用来分类用户

Permission:执行特定操作的标识


这个框架还包含默认的认证(authentication)视图(views)和表单(forms),我们之后会用到。

注:请注意authenticationlogin中的不同点:authenticate()检查用户认证信息,如果用户是正确的则返回一个用户对象;login()将用户设置到当前的会话(session)中。


使用Django认证(authentication)视图(views)

Django在认证(authentication)框架中包含了一些开箱即用的:表单(forms)和视图(views)。

你之前创建的登录视图(view)是一个非常好的练习用来理解Django中的用户认证(authentication)过程。无论如何,你可以在大部分的案例中使用默认的Django认证(authentication)视图(views)


Django提供以下视图(views)来处理认证(authentication)

login:操作表单(form)中的登录然后登录一个用户

logout:登出一个用户

logout_then_login:登出一个用户然后重定向这个用户到登录页面


Django提供以下视图(views)来操作密码修改

password_change:操作一个表单(form)来修改用户密码

password_change_done:当用户成功修改他的密码后提供一个成功提示页面


Django还包含了以下视图(views)允许用户重置他们的密码:

password_reset:允许用户重置他的密码。它会生成一条带有一个token的一次性使用链接然后发送到用户的邮箱中

password_reset_done:告知用户已经发送了一封可以用来重置密码的邮件到他的邮箱中。

password_reset_complete:当用户重置完成他的密码后提供一个成功提示页面


        在你的account应用中的template目录下创建一个新的目录命名为registration。这个路径是Django认证(authentication)视图(view)期望你的认证(authentication)模块(template)默认的存放路径。


用户登录

<div>

        <form action={% url "login" %} method="post">

                {{ form.as_p }}

                {% csrf_token %}

                <input type="hidden" name="next" value="{{ next }}"/>

                <p><input type="submit" value="登录"></p>

        </form>

</div>

Django默认使用位于django.contrib.auth.forms中的AuthenticationForm。这个表单(form)会尝试对用户进行认证,如果登录不成功就会抛出一个验证错误。如果提供了错误的认证信息,我们可以在模板(template)中使用{% if form.errors %}来找到错误。

注意:

      (1).我们添加了一个隐藏的HTML元素来提交叫做next的变量值。当你在请求(request)中传递一个next参数(举个例子:http://127.0.0.1:8000/account/login/?next=/account/),这个变量是登录视图(view)首个设置的参数。next参数必须是一个URL。当这个参数被给予的时候,Django登录视图(view)将会在用户登录完成后重定向到给予的URL。

    (2).在我们的地址配置中所包含的logtou_then_login视图(view)不需要任何模板(template),因为它执行了一个重定向到登录视图(view)。

    (3).login_required装饰器(decorator)会检查当前用户是否通过认证,如果用户没有通过认证,它会把用户重定向到带有一个名为next的GET参数的登录URL,该GET参数保存的变量为用户当前尝试访问的页面URL。


from django.core.urlresolvers import reverse_lazy

LOGIN_REDIRECT_URL = reverse_lazy('dashboard')

LOGIN_URL = reverse_lazy('login')

LOGOUT_URL = reverse_lazy('logout')

这些设置的意义:

LOGIN_REDIRECT_URL:告诉Django用户登录成功后如果contrib.auth.views.login视图(view)没有获取到next参数将会默认重定向到哪个URL。

LOGIN_URL:重定向用户登录的URL(例如:使用login_required装饰器(decorator))。

LOGOUT_URL:重定向用户登出的URL。

        我们使用reverse_lazy()来通过它们的名字动态构建URL。reverse_lazy()方法就像reverse()所做的一样reverses URLs,但是你可以通过使用这种方式在你项目的URL配置被读取之前进行reverse URLs。


        通过认证(authentication)中间件当前的用户被设置在HTTP请求(request)对象中。你可以通过使用request.user访问用户信息。你会发现一个用户对象在请求(request)中,即便这个用户并没有认证通过。一个未认证的用户在请求(request)中被设置成一个AnonymousUser的实例。一个最好的方法来检查当前的用户是否通过认证是通过调用request.user.is_authenticated()。

如果在你的登出页面中看到了Django管理站点的登出页面,检查项目settings.py中的INSTALLED_APPS,确保django.contrib.admin在account应用的后面


修改密码视图(views)

password_change视图(view)将会操作表单(form)进行修改密码,当用户成功的修改他的密码后password_change_done将会显示一条成功信息。

password_reset_email.html(渲染发送给用户的重置密码邮件)

Someone asked for password reset for email {{ email }}. Follow the link below:

{{ protocol }}://{{ domain }}{% url "password_reset_confirm" uidb64=uid token=token %}

Your username, in case you've forgotten: {{ user.get_username }}


再创建另一个模板(template)password_reset_confirm.html,为它添加如下代码:

{% block content %}

        Reset your password

            {% if validlink %}

                        Please enter your new password twice:

                        {{ form.as_p }}

                        {% csrf_token %}

                        <input type="submit" value="修改密码">

            {% else %}

                    The password reset link was invalid, possibly because it has already been used. Please request a new password reset.

            {% endif %}

{% endblock %}

在以上模板中,我们将会检查重置链接是否有效。Django重置密码视图(view)会设置这个变量然后将它带入这个模板(template)的上下文环境中。如果重置链接有效,我们展示用户密码重置表单(form)。


用户注册

Django还提供一个UserCreationForm表单(form)给你使用,它位于django.contrib.auth.forms非常类似与我们刚才创建的表单(form)。

编辑他们的pfofile:

        user_form = UserEditForm(instance=request.user,data=request.POST)


使用一个定制User模型(model)

        Django还提供一个方法可以使用你自己定制的模型(model)来替代整个User模型(model)。你自己的用户类需要继承Django的AbstractUser类,这个类提供了一个抽象的模型(model)用来完整执行默认用户


使用messages框架

当处理用户的操作时,你可能想要通知你的用户关于他们操作的结果。Django有一个内置的messages框架允许你给你的用户显示一次性的提示。

messages框架提供了一个简单的方法添加消息给用户。消息被存储在数据库中并且会在用户的下一次请求中展示。你可以在你的视图(views)中导入messages模块来使用消息messages框架,用简单的快捷方式添加新的messages

from django.contrib import messages

messages.error(request, 'Something went wrong')

你可以使用add_message()方法创建新的messages或用以下任意一个快捷方法:

success():当操作成功后显示成功的messages

info():展示messages

warning():某些还没有达到失败的程度但已经包含有失败的风险,警报用

error():操作没有成功或者某些事情失败

debug():在生产环境中这种messages会移除或者忽略


创建一个定制的认证(authentication)后台

Django允许你通过不同的来源进行认证(authentication)。AUTHENTICATION_BACKENDS设置包含了所有的给你的项目的认证(authentication)后台。

1.('django.contrib.auth.backends.ModelBackend',)---默认的ModelBackend通过数据库使用django.contrib.auth中的User模型(model)来认证(authentication)用户。

2.当你使用django.contrib.auth的authenticate()函数,Django会通过每一个定义在AUTHENTICATION_BACKENDS中的后台一个接一个地尝试认证(authentication)用户,直到其中有一个后台成功的认证该用户才会停止进行认证。只有所有的后台都无法进行用户认证(authentication),他或她才不会在你的站点中通过认证(authentication)。


Django提供了一个简单的方法来定义你自己的认证(authentication)后台。一个认证(authentication)后台就是提供了如下两种方法的一个类:

authenticate():将用户信息当成参数,如果用户成功的认证(authentication)就需要返回True,反之,需要返回False

get_user():将用户的ID当成参数然后需要返回一个用户对象

创建一个定制认证(authentication)后台非常容易,就是编写一个Python类实现上面两个方法。我们要创建一个认证(authentication)后台让用户在我们的站点中使用他们e-mail替代他们的用户名来进行认证(authentication)。

class EmailAuthBackend(object):

        def authenticate(self, username=None, password=None):

                try:

                        user = User.objects.get(email=username)

                        if user.check_password(password):

                                return user

                        return None

                except User.DoesNotExist:

                        return None

        def get_user(self, user_id):

                try:

                        return User.objects.get(pk=user_id)

                except User.DoesNotExist:

                        return None

authenticate():我们尝试通过给予的e-mail地址获取一个用户和使用User模型(model)中内置的check_password()方法来检查密码。这个方法会对给予密码进行哈希化来和数据库中存储的加密密码进行匹配。

get_user():我们通过user_id参数获取一个用户。Django使用这个后台来认证用户之后取回User对象放置到持续的用户会话中。

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

推荐阅读更多精彩内容