`
siu23
  • 浏览: 16635 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

用户模板Django1.5内置的用户认证系统介绍(之四)Authentication in Web requests

阅读更多

发一下牢骚和主题无关:

    说明:网上有关Django用户系统的内容不少,但是像好没有针对Django1.5的。可能是因为Django1.5前目用的人还多不吧。(python3.x貌似也是种这况情)。因为自己要用,所以顺手在学习官方文档的过程当中,边看边译。基本忠于原文(>95%),小分部太啰嗦的内容就当适意译、简化了。后续还会入加分部自己的会体(会注出),供参考。如有错讹、不确准的地方,还请大家指教。

    Source:
https://docs.djangoproject.com/en/1.5/topics/auth/default/#auth-web-requests

    

Web请求中的证认 Authentication in Web requests

    Django应用sessions 和 middleware来接链证认系统与请求对象(request objects)。

    在个每Web请求中都供给一个 request.user 属性来表现以后用户。如果以后用户未录登,则该属性为AnonymousUser的一个实例,反之,则是一个User实例。

    你可以通过is_authenticated()来辨别,例如:

if request.user.is_authenticated():
    # Do something for authenticated users.
else:
    # Do something for anonymous users.

如何录登 How to log a user in

    你可以用login()数函来将证认用户入加到以后session中。

    login()

    在view中应用来录登用户。参数包含一个HttpRequest对象和一个User对象。login() 将用户ID保存到session中(应用Django session framework)。

    意注:当用户陆登后对于匿名session的任何据数设置会都保留在session中。

    下面的例子来范示如何同时应用 authenticate() 和 login():

from django.contrib.auth import authenticate, login
 
def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
    else:
        # Return an 'invalid login' error message.

首先用调authenticate() 

    如果你自己写代码,一定要保确首先用调authenticate(),然后再用调login()。 authenticate() 会设置User的一个属性来知通证认台后该用户经已功成证认(体具见参: backends documentation),这个属性息信在后续的login处置中须要。因此,如果你直接用调login就会抛出异常。

    

如何登出How to log a user out

    logout()

    通过 django.contrib.auth.login()录登的用户登出时要在view中应用django.contrib.auth.logout() 。应用HttpRequest对象为参数,无返回值。例如:

from django.contrib.auth import logout
 
def logout_view(request):
    logout(request)
    # Redirect to a success page.

意注:logout()不会抛出异常,即应用户并没有录登。

    当用调logout()时,以后请求的session据数会完全清空。如果你须要在用户登出后应用session中的据数,务必在用调django.contrib.auth.logout()后在设置。

    

制限拜访 Limiting access to logged-in users

    

浅易法方 The raw way

    最简略直接的式方是:查检request.user.is_authenticated(),如果为False则重定向到录登页面。

from django.shortcuts import redirect
 
def my_view(request):
    if not request.user.is_authenticated():
        return redirect('/login/?next=%s' % request.path)
    # ...

...或示显错误息信:

from django.shortcuts import render
 
def my_view(request):
    if not request.user.is_authenticated():
        return render(request, 'myapp/login_error.html')
    # ...

login_required 修饰符

    login_required([redirect_field_name=REDIRECT_FIELD_NAMElogin_url=None])

    更简练的,你可以应用login_required() 修饰符:

from django.contrib.auth.decorators import login_required
 
@login_required
def my_view(request):
    ...

login_required() 成完以下作工:

    

  • 如果用户未录登,则重定向到settings.LOGIN_URL,在Query String中传递以后绝对路径。例如: /accounts/login/?next=/polls/3/.
  • 如果用户已录登,则常正执行view。在View的代码可定假用户经已录登。

    一般,用户在功成证认后重定向的接链保存在query string的next参数。如果你想用其他参数名。login_required()中有可选的redirect_field_name参数。

from django.contrib.auth.decorators import login_required
 
@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
    ...

意注:如果你设置了redirect_field_name,你可能还须要在你的login模板中做应相修改。因为保存重定向路径的模板上下文变量(template context variable)将应用参数 redirect_field_name的值作为key。

    login_required() 还供给一个可选的 login_url 参数,例如:

from django.contrib.auth.decorators import login_required
 
@login_required(login_url='/accounts/login/')
def my_view(request):
    ...

意注:如果你不指定login_url参数,你须要保确settings.LOGIN_URL和你的login view 经已确准联关了。例如:在URLconf入加如下缺省内容。

(r'^accounts/login/$', 'django.contrib.auth.views.login'),

Changed in Django 1.5.

    settings.LOGIN_URL 也可以受接view数函和named URL patterns。这使得你可以自在义定自己的login view,而不须要去改更你的URLconf设置。

    意注:login_required修饰符不会查检user的is_active标志位。

    

拜访制限 Limiting access to logged-in users that pass a test

    基于特定查检来行进拜访控制,基本和之前章节分析的式方似类。

    最简略的式方就是在view中直接应用request.user。例如:下面的view查检用户有具特定domain的email。

def my_view(request):
    if not '@example.com' in request.user.email:
        return HttpResponse("You can't vote in this poll.")
    # ...

user_passes_test(func[, login_url=None])

    更简略的的,你可以直接应用 user_passes_test 修饰符:

from django.contrib.auth.decorators import user_passes_test
 
def email_check(user):
    return '@example.com' in user.email
 
@user_passes_test(email_check)
def my_view(request):
    ...

user_passes_test() 用“可用调的数函”作为参数,该数函用User作为入输参数,返回布尔值来说明是不是通过查检。意注: user_passes_test() 不会动自查检此时用户是不是经已录登。

    user_passes_test() 还有一个可选的login_url参数,从而可以指定录登页面。(缺省用采settings.LOGIN_URL

    例如:

@user_passes_test(email_check, login_url='/login/')
def my_view(request):
    ...

permission_required修饰符

    permission_required([login_url=Noneraise_exception=False])

    Django供给一种简略的式方来断判用户是不是具有某种权限: permission_required() 修饰符:

from django.contrib.auth.decorators import permission_required
 
@permission_required('polls.can_vote')
def my_view(request):
    ...

has_perm() 法方中,权限名称用采<app label>.<permission codename>的格式(例如polls.can_vote表现在poll应用中的权限)。

    意注:permission_required() 也含包一个可选的login_url参数,例如:

from django.contrib.auth.decorators import permission_required
 
@permission_required('polls.can_vote', login_url='/loginpage/')
def my_view(request):
    ...

login_required() 修饰符一样,login_url缺省值为settings.LOGIN_URL.

    Changed in Django 1.4.

    增加了 raise_exception参数,如果给定,修饰符将抛出PermissionDenied,然后示提 the 403 (HTTP Forbidden) view而不是重定向到录登页面。

    

给泛型views应用权限Applying permissions to generic views

    如果要给class-based generic view应用权限,则须要给类加上View.dispatch的修饰符。详见: Decorating the class.

    

证认Views Authentication Views

    Django内置供给了几个views可以用来处置录登、登出和密码管理等。这些功能应用了stock auth forms 表单,但也可以自己义定表单。

    Django没无为证认views供给缺省模板,但模板上下文可为以view供给 however the template context is documented for each view below.

    New in Django 1.4.

    全部内置(built-in)views都返回一个TemplateResponse实例,可以让你很便方的定制response据数。体具见参:TemplateResponse documentation.

    少数的内置证认views都供给一个URL名称以便应用,体具见参:the URL documentation

    login(request[, template_nameredirect_field_nameauthentication_form])

    URL name: login

    体具见参: the URL documentation.

    django.contrib.auth.views.login 作工道理:

    

  • 如果是GET法方, 将示显录登表单,可以将其内容POST到雷同的URL上,不再赘述。
  • 如果是POST 法方,用户提交了安全证凭。它首先会实验录登,如果功成,view就重定向到next指定的的接链。如果next 未设置,则重定向到settings.LOGIN_REDIRECT_URL(一般缺省值为accounts/profile/)。如果录登失败,则再次示显录登表单。

    须要用户自己来供给login的html模板,缺省是registration/login.html 。这个模板将传递4个模板上下文变量:

    每日一道理
生活的无奈,有时并不源于自我,别人无心的筑就,那是一种阴差阳错。生活本就是矛盾的,白天与黑夜间的距离,春夏秋冬之间的轮回,于是有了挑剔的喜爱,让无奈加上了喜悦的等待。

    

  • form: 一个表单对象,表现AuthenticationForm.
  • next: 录登功成后的重定向接链,可以含包一个query string中。
  • site: 以后网站,根据 SITE_ID 设置。如果你并没有装安site框架,这个变量将设定为一个 RequestSite实例,它从以后 HttpRequest中获得站点名和域名。
  • site_name: 是 site.name的一个别名。如果你没有装安site框架,它将会被设为 request.META['SERVER_NAME']的值。体具见参 The “sites” framework.

    如果你不想用调registration/login.html模板,你可以在URLconf中设定特定的view参数来传递template_name参数。例如:下面的URLconf 设置将应用 myapp/login.html 作为模板:

(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),

你也可以自己指定录登功成后的重定向接链段字名,通过redirect_field_name 参数。默许的段字名为next.

    下面是registration/login.html 模板的原始态状,它定假你有一个base.html模板(其中有content block的义定。

{% extends "base.html" %}
 
{% block content %}
 
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
 
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
    <td>{{ form.username.label_tag }}</td>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <td>{{ form.password.label_tag }}</td>
    <td>{{ form.password }}</td>
</tr>
</table>
 
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
 
{% endblock %}

如果你定制实现了证认(体具见参: Customizing Authentication)你可以通过 authentication_form 参数把自义定的证认表单传给login view。该表单的__init__ 法方应该有一个request 的参数,并供给一个 get_user 法方来返回证认后的User对象。

    logout(request[, next_pagetemplate_nameredirect_field_name])

    登出/注销用户.

    URL name: logout

    可选参数 Optional arguments:

    

  • next_page: 注销后的重定向接链.
  • template_name: 注销后的模板名称。默许值为registration/logged_out.html 。
  • redirect_field_name: 含包重定向接链的段字名称,缺省值为next_page

    模板上下文变量 Template context:

    

  • title: 本地化的 “Logged out”字串.
  • site: 以后网站,根据 SITE_ID 设置。如果你并没有装安site框架,这个变量将设定为一个 RequestSite实例,它从以后 HttpRequest中获得站点名和域名。
  • site_name: 是 site.name的一个别名。如果你没有装安site框架,它将会被设为 request.META['SERVER_NAME']的值。体具见参 The “sites” framework.

    logout_then_login(request[, login_url])

    注销用户然后重定向到录登接链.

    URL name: 为供给缺省接链

    可选参数 Optional arguments:

    

    password_change(request[, template_namepost_change_redirect,password_change_form])

    许允用户修改密码.

    URL name: password_change

    可选参数 Optional arguments:

    

  • template_name: 密码修改表单的模板名,缺省值为registration/password_change_form.html 。
  • post_change_redirect: 密码修改后的重定向接链。
  • password_change_form: 自义定的密码修改表单,包含一个user 参数。缺省值为PasswordChangeForm.

    模板上下文变量 Template context:

    

  • form: 密码修改表单 (见参下面的 password_change_form ).

    password_change_done(request[, template_name])

    用户修改密码后的页面.

    URL name: password_change_done

    可选参数 Optional arguments:

    

  • template_name: 模板名称,缺省为registration/password_change_done.html.

    password_reset(request[, is_admin_sitetemplate_nameemail_template_name,password_reset_formtoken_generatorpost_reset_redirectfrom_email])

    通过发送邮件(含包一个只能一次性应用的接链),来让用户重设密码。

    Changed in Django 1.4: 

    标识“未应用密码”(unusable password) (体具见参set_unusable_password() )的用户不能请求重置密码。这样可以避免像LDAP这样的外部证认源的。

    URL name: password_reset

    可选参数 Optional arguments:

    

  • template_name: 模板名称,缺省值为registration/password_reset_form.html。
  • email_template_name: 用来成生带值充接链email的模板名称,缺省值为registration/password_reset_email.html。
  • subject_template_name: 用来成生邮件主题的模板名称,缺省值为  registration/password_reset_subject.txt。

    New in Django 1.4.

    

  • password_reset_form: 重设密码的表单,缺省值为 PasswordResetForm.
  • token_generator: 查检一次性接链的类实例,缺省值为default_token_generator, 其类为django.contrib.auth.tokens.PasswordResetTokenGenerator.
  • post_reset_redirect: 密码重置后的重定向接链.
  • from_email: 邮件地址,缺省值为DEFAULT_FROM_EMAIL.

    模板上下文变量 Template context:

    

  • form: 密码重置的表单 (见上: password_reset_form )

    Email模板上下文变量 Email template context:

    

  • email: user.email的别名
  • user: 以后用户,发邮件时将获得其 email 段字。只有激活的用户才能重置密码。 (User.is_active is True).
  • site_name: site.name的别名。如果你未装安site framework,则取request.META['SERVER_NAME']的值. 具体见参:The “sites” framework.
  • domain: site.domain的别名. 如果你未装安site framework,则取request.get_host()的值。
  • protocol: http 或 https
  • uid: 用户ID(base 36码编).
  • token: 用来查检接链是不是有效的token(令牌).

    示例: registration/password_reset_email.html (email内容模板):

Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %}

雷同的模板变量也用在subject template中。邮件主题(Subject)必须是单行文本字符串。

    password_reset_done(request[, template_name])

    示显用户择选发送密码重置邮件后的页面。如果 password_reset() view中没有显式指定post_reset_redirect接链时,则直接用调本view。

    URL name: password_reset_done

    Optional arguments:

    

  • template_name:模板名称,缺省值为registration/password_reset_done.html 

    password_reset_confirm(request[, uidb36tokentemplate_nametoken_generator,set_password_formpost_reset_redirect])

    示显入输新密码的表单.

    URL name: password_reset_confirm

    Optional arguments:

    

  • uidb36: 用户ID(base 36码编)。缺省值为None.
  • token:用来查检密码是不是有效的token,缺省值为 None.
  • template_name: 示显密码确认的模板名称,缺省值为: registration/password_reset_confirm.html.
  • token_generator: 查检密码类的实例,缺省值为default_token_generator, 其类为:django.contrib.auth.tokens.PasswordResetTokenGenerator.
  • set_password_form: 设定密码的表单,缺省值为SetPasswordForm
  • post_reset_redirect: 密码重置后的重定向,缺省值为None.

    模板上下文变量 Template context:

    

  • form: 密码设置表单 (见上:set_password_form )
  • validlink: Boolean, 重置接链是不是有效

    password_reset_complete(request[, template_name])

    view:知通用户经已功成重置了密码

    URL name: password_reset_complete

    Optional arguments:

    

  • template_name: 模板名称,缺省值registration/password_reset_complete.html.

    

Helper functions

    redirect_to_login(next[, login_urlredirect_field_name])

    重定向到录登页面,录登功成后的在重定向到另外一接链。.

    Required arguments:

    

  • next: 录登功成后的接链.

    Optional arguments:

    

  • login_url: 陆登页面接链,缺省值:settings.LOGIN_URL
  • redirect_field_name: 重定向段字名称,缺省值为next。

    

内置表单 Built-in forms

    如果你不想应用内置的view,也不想从新写应相的表单,仍可以应用django供给相干的表单,在django.contrib.auth.forms中:

    意注 Note

    内置的证认表单与缺省的User模型对应,如果你应用自义定的用户模型(custom User model),那可能须要自己义定相干的表单。体具的,见参文档using the built-in authentication forms with custom user models.

    class AdminPasswordChangeForm

    admin台后的用户密码修改表单

    class AuthenticationForm

    用户录登表单.

    class PasswordChangeForm

    修改密码表单.

    class PasswordResetForm

    密码重置表单.

    class SetPasswordForm

    密码设置表单.

    class UserChangeForm

    admin台后的用户息信和权限修改表单.

    class UserCreationForm

    用户创立表单.

    

模板中的证认息信 Authentication data in templates

    以后录登用户及其权限可以在模板变量( template context)中获得,应用RequestContext.

    术语 Technicality

    下述模板变量仅在应用RequestContextTEMPLATE_CONTEXT_PROCESSORS 配置含包"django.contrib.auth.context_processors.auth"时有效(即缺省配置)。体具见参RequestContext docs.

    

Users

    在染渲模板 RequestContext时,以后的录登用户(无论是User实例还是AnonymousUser 实例)均保存在模板变量 {{ user }}:

{% if user.is_authenticated %}
    <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
    <p>Welcome, new user. Please log in.</p>
{% endif %}

如果未应用 RequestContext,则此变量不存在。

    

权限 Permissions

    以后录登用户的权限保存在模板变量 {{ perms }}中,是django.contrib.auth.context_processors.PermWrapper的实例,该类是一个模板可应用的权限代理类。

 {{ perms }} 对象中,单属性查询实际上是User.has_module_perms的一个代理。下面是一个例子:如果录登用户在foo中有拥权限则为True。

{{ perms.foo }}

两级属性查询则是User.has_perm的代理,下面的例子中,如果录登用户有拥权限 foo.can_vote则为True

{{ perms.foo.can_vote }}

这样,你就能够在模板用中 {% if %} 语句来查检权限了:

{% if perms.foo %}
    <p>You have permission to do something in the foo app.</p>
    {% if perms.foo.can_vote %}
        <p>You can vote!</p>
    {% endif %}
    {% if perms.foo.can_drive %}
        <p>You can drive!</p>
    {% endif %}
{% else %}
    <p>You don't have permission to do anything in the foo app.</p>
{% endif %}

New in Django 1.5: 用 “if in”.来查询权限

    可以直接通过 {% if in %} 语句查询权限,例如:

{% if 'foo' in perms %}
    {% if 'foo.can_vote' in perms %}
        <p>In lookup works, too.</p>
    {% endif %}
{% endif %}

文章结束给大家分享下程序员的一些笑话语录: 那是习惯决定的,一直保持一个习惯是不好的!IE6的用户不习惯多标签,但是最终肯定还是得转到多标签的浏览器。历史(软件UI)的进步(改善)不是以个人意志(习惯)为转移的!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics