网页的登录

Part 1

确定settings.py中,SessionMiddlewareINSTALLED_APPS设置中的'django.contrib.sessions’ 没有被注释掉。

简单的测试一下seesion的功能,直接用request.session["sessionName"]引用就可以了,也可以删除del ..

做个实例~~

增加一个登录模板:login_form.html:

1
2
3
4
5
<html> <body> <form action="" method="post">
<table> <input type="text" name="user">
<input type="password" name="passwd">
</table><input type="submit" value="Submit">
</form></body></html>

urls.py中增加一个对应选项

(r'^login/$', views.login),

views.py中增加对应的处理函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.contrib import auth
def login(request):
# 如果提交form
if request.method == 'POST':
# 测试cookie是否工作:
if request.session.test_cookie_worked():
#如果cookie工作,就删除.
request.session.delete_test_cookie()
# 我们这里需要验证用户
user = auth.authenticate(username=request.POST['user'], password=request.POST['passwd'])
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponse("login correct: " + request.POST['user'] + " : my cookie:" + request.session["mytest"])
else:
auth.logout(request) # 登录不正确,自动退出
return HttpResponse("login incorrect: " + request.POST['user'])
else:
return HttpResponse("需要cookie支持。")
#如果不是post方法,就显示网页.
request.session.set_test_cookie()
request.session["mytest"] = "my test is just like that."
return render_to_response('login_form.html')

运行服务器,访问http://127.0.0.1:8000/login,就可以看到结果。

列出你的服务器所有cookie内容.dos下进入到mysite目录,运行manage.py shell

1
2
>>> for i in Session.objects.all():
... print i.get_decoded(), i.pk

可以根据pk值进行查询,也可以访问http://127.0.0.1:8000/look可以看到你的sessionid,然后可以单独查询.

1
2
3
4
5
6
7
8
>>> s = Session.objects.get(pk="2271b2b1477c49c13ac9774a974229b0")
>>> s.expire_date
datetime.datetime(2010, 4, 2, 0, 0, 0, 0)
>>> s.session_data
u'gAJ9cQFVBm15dGVzdHECVRpteSB0ZXN0IGlzIGp1c3QgbGlrZSB0aGF0LnEDcy44OWFmNmRlZDU0\n
NTczZTk0ZGUyNTkzMjYyODEyNTQ3NA==\n'
>>> s.get_decoded()
{'mytest': 'my test is just like that.'}

session过期默认是2个周,SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 False , SESSION_COOKIE_AGE 保存多少秒

SESSION_COOKIE_DOMAIN 使用会话cookie(session cookies)的站点。将它设成一个字符串,就好象“`.example.com`” 以用于跨站点(cross-domain)的cookie,或`` `None

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
`SESSION_COOKIE_NAME` 会话中使用的cookie的名字。 它可以是任意的字符串。 "sessionid"
`SESSION_COOKIE_SECURE` 是否在session中使用安全cookie, 如果设置 `True` , cookie就会标记为安全, 这意味着cookie只会通过HTTPS来传输
django提供认证授权的支持,前面已经在settings.py中打开了. 访问[http://127.0.0.1:8000/admin/](http://127.0.0.1:8000/admin/)就可以登录了.
判断授权的用户可以用`request.user.is_authenticated()`.
## user的属性 ##
- `username` 必需的,不能多于30个字符。 仅用字母数字式字符(字母、数字和下划线)。
- `first_name` 可选; 少于等于30字符.
- `last_name` 可选; 少于等于30字符.
- `email` 可选. 邮件地址.
- `password` 密码的哈希值,django不保存明码.
- `is_staff` 布尔值. 用户是否拥有网站的管理权限.
- `is_active` 布尔值. 用户是否拥有所有权限,而无需任何显式的权限分配定义用户最后登录的时间,缺省会设置为当前时间
- `is_superuser Boolean`. Designates that this user has all - permissions without explicitly assigning them.
- `last_login` 用户上次登录的时间日期。 它被默认设置为当前的日期/时间。
- `date_joined` 账号被创建的日期时间 当账号被创建时,它被默认设置为当前的日期/时间。
通过用户也可以得到用户`groups`和授权`permissions`表的引用.
```py
myuser.groups = group_list
# 增加用户到某组:
myuser.groups.add(group1, group2,...)
# 删除某组
myuser.groups.remove(group1, group2,...)
# 删除所有
myuser.groups.clear()
# 授权
myuser.permissions = permission_list
myuser.permissions.add(permission1, permission2, ...)
myuser.permissions.remove(permission1, permission2, ...)
myuser.permissions.clear()

django手工认证.(自己增加一个用户,检查就好.)

1
2
3
4
5
6
>>> from django.contrib import auth
>>> user = auth.authenticate(username='derris', password='xman123')
>>> if user is not None and user.is_active:
... print "Correct!"
... else:
... print "Invalid password."

在视图里面,就可以用auth.login(request, user),完成登录了.

django提供自动的登录视图,只需要指定对应的模板就可以处理。(还是自己处理简单。。。)

1
2
3
4
5
6
from django.contrib.auth.views import login, logout
urlpatterns = patterns('',
# existing patterns here...
(r'^accounts/login/$', login),
(r'^accounts/logout/$', logout),
)

模板要包括这些东东:next的内容是自动在登录以后重新定向的url(缺省会重定向到 /accounts/profile )

1
2
3
4
5
6
7
8
9
10
11
{% if form.errors %}
<p class="error">Sorry, that's not a valid username or password</p>
{% endif %}
<form action="" method="post">
<label for="username">User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next|escape }}" />
</form>

对于需要登录的视图函数,可以加个修饰符。

1
2
3
4
5
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
# ...
#如果用户没有登录,就无法访问改页啦,如果想自动到登录页面,就要使用django系统的login模板~~。

检查用户是否有访问资源的权限用:request.user.has_perm('xxxx'))就可以了。权限在admin管理里面可以设置。

也有对应的修饰符:

1
2
3
4
5
def user_can_vote(user):
return user.is_authenticated() and user.has_perm("polls.can_vote")
@user_passes_test(user_can_vote, login_url="/login/")
def vote(request):
# Code here can assume a logged-in user with the correct permission.

还有更简单的:

1
2
3
4
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote', login_url="/login/")
def vote(request):
# ...

后面不打算自己开发用~~简单记录一下:

创建用户使用 create_user 辅助函数创建用户:

1
2
3
4
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user(username='john',
... email='[email protected]',
... password='glass onion')

在这里, user 是 User 类的一个实例,准备用于向数据库中存储数据。 create_user()函数并没有在数据库中创建记录,在保存数据之前,你仍然可以继续修改它的属性值。

1
2
>>> user.is_staff = True
>>> user.save()

修改密码你可以使用 set_password() 来修改密码:

1
2
3
>>> user = User.objects.get(username='john')
>>> user.set_password('goo goo goo joob')
>>> user.save()

除非你清楚的知道自己在做什么,否则不要直接修改 password 属性。 其中保存的是密码的 加入salt的hash值 ,所以不能直接编辑。

一般来说, User 对象的 password 属性是一个字符串,格式如下:

hashtype$salt$hash

这是哈希类型,salt和哈希本身,用美元符号($)分隔。

hashtype 是 sha1 (默认)或者 md5 ,它是用来处理单向密码哈希的算法,Salt是一个用来加密原始密码来创建哈希的随机字符串,例如: salt is a random string used to salt the raw password to create the hash, for example:

sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4

User.set_password()User.check_password() 函数在后台处理和检查这些值。

加了salt是为了防止对单向哈希值进行字典对应查找破解,就算知道salt的算法,也要一个一个的计算,增加破解难度。

创建自己的用户注册功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/books/")
else:
form = UserCreationForm()
return render_to_response("registration/register.html", {
'form': form,
})

这个表单构想了一个叫 registration/register.html 的模板. 这里是一个这个模板的可能的样子的例子:

1
2
3
4
5
6
7
8
9
{% extends "base.html" %}
{% block title %}Create an account{% endblock %}
{% block content %}
<h1>Create an account</h1>
<form action="" method="post">
{{ form.as_p }}
<input type="submit" value="Create the account">
</form>
{% endblock %}

从技术上来说,只有当你使用了 RequestContext 并且 TEMPLATE_CONTEXT_PROCESSORS 设置包含了 “django.core.context_processors.auth” (默认情况就是如此)时,这些变量才能在模板context中使用。

当使用 RequestContext 时, 当前用户 (是一个 User 实例或一个 AnonymousUser 实例) 存储在模板变量 中:

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

这些用户的权限信息存储在 模板变量中。

你有两种方式来使用 perms 对象。 你可以使用类似于 的形式来检查,对于某个特定的应用,一个用户是否具有 任意 权限;你也可以使用 这样的形式,来检查一个用户是否拥有特定的权限。

这样你就可以在模板中的 if标签 语句中检查权限:

1
2
3
4
5
6
7
8
{% if perms.polls %}
<p>You have permission to do something in the polls app.</p>
{% if perms.polls.can_vote %}
<p>You can vote!</p>
{% endif %}
{% else %}
<p>You don't have permission to do anything in the polls app.</p>
{% endif %}

消息系统会为给定的用户接收消息。 每个消息都和一个 User 相关联。

在每个成功的操作以后,Django的admin管理接口就会使用消息机制。 例如,当你创建了一个对象,你会在admin页面的顶上看到 The object was created successfully 的消息。

你也可以使用相同的API在你自己的应用中排队接收和显示消息。 API非常地简单:

要创建一条新的消息,使用user.message_set.create(message='message_text')

要获得/删除消息,使用 user.get_and_delete_messages() ,这会返回一个 Message 对象的列表,并且从队列中删除返回的项。

在例子视图中,系统在创建了播放单(playlist)以后,为用户保存了一条消息。

1
2
3
4
5
6
7
8
def create_playlist(request, songs):
# Create the playlist with the given songs.
# ...
request.user.message_set.create(
message="Your playlist was added successfully."
)
return render_to_response("playlists/create.html",
context_instance=RequestContext(request))

当使用 RequestContext ,当前登录的用户以及他(她)的消息,就会以模板变量 出现在模板的context中。

1
2
3
4
5
6
7
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}

热评文章