django認(rèn)證系統(tǒng)包含三個(gè)部分:用戶、權(quán)限和分組
django項(xiàng)目默認(rèn)啟用了認(rèn)證系統(tǒng),如果不是使用django-admin.py創(chuàng)建項(xiàng)目的可以通過(guò)在settings配置文件里面的INSTALLED_APPS的列表里面添加django.contrib.auth和django.contrib.contenttypes這兩項(xiàng)然后運(yùn)行manage.py syncdb命令創(chuàng)建對(duì)應(yīng)的數(shù)據(jù)庫(kù)表即可
在Django-1.4.10/django/contrib/auth這個(gè)目錄下有一個(gè)model文件,里面有Permission,GroupManager,Group,UserManager,User,AnonymousUser這些類(lèi)的源碼,建議自己都去看一下,很多注釋?zhuān)瑢傩悦头椒纪ㄋ滓锥?,這里只點(diǎn)一下關(guān)鍵點(diǎn)
groups和user_permissions是是多對(duì)多的屬性,分別對(duì)應(yīng)到了類(lèi)Group和Permission
is_active這個(gè)屬性提醒我們不要輕易的刪掉一些對(duì)象,我們可以設(shè)置一個(gè)標(biāo)志位標(biāo)識(shí)該對(duì)象是否可用
set_unusable_passWord,標(biāo)識(shí)該用戶沒(méi)有密碼設(shè)置,注意不等同與空密碼
>>> from django.contrib.auth.models import User>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')>>> user.save()修改密碼,注意是使用set_password而不是password屬性
>>> from django.contrib.auth.models import User>>> u = User.objects.get(username__exact='john')>>> u.set_password('new password')>>> u.save()創(chuàng)建超級(jí)用戶
manage.py createsuperuser --username=joe --email=joe@example.com存儲(chǔ)用戶的額外信息
這是一個(gè)比較麻煩的事情,不過(guò)django還是提供了一個(gè)定制的方法
首先你要定義一個(gè)模型,在這個(gè)模型里面你可以定制額外的屬性或者方法,然后記得添加一個(gè)名為user的一對(duì)一的屬性名

from django.contrib.auth.models import Userclass UserPRofile(models.Model): # 必選 user = models.OneToOneField(User) # 自定義的屬性或者方法 accepted_eula = models.BooleanField() favorite_animal = models.CharField(max_length=20, default="Dragons.")
為了表明這個(gè)模型是對(duì)于那個(gè)給定的站點(diǎn),我們還需要配置一個(gè)AUTH_PROFILE_MODULE,這是一個(gè)字符串,包含兩部分信息,由點(diǎn)號(hào)相連
app名:大小寫(xiě)敏感,一般是你使用manage.py startapp創(chuàng)建時(shí)用的名稱(chēng)你自定義的模型名稱(chēng),大小寫(xiě)不敏感比如,app名為accounts,模型名為UserProfile
AUTH_PROFILE_MODULE = 'accounts.UserProfile'一旦一個(gè)用戶檔案模型(額外信息模型)被定義然后用上述方法指明,每一個(gè)user對(duì)象都會(huì)有一個(gè)方法--get_profile()--去返回跟該用戶相關(guān)的額外信息
然而,你必須注冊(cè)一個(gè)到django.db.models.signals.post_save信號(hào)的處理程序,并且在處理程序里面,如果created為真,才創(chuàng)建關(guān)聯(lián)的用戶額外信息

# in models.pyfrom django.contrib.auth.models import Userfrom django.db.models.signals import post_save# definition of UserProfile from above# ...def create_user_profile(sender, instance, created, **kwargs): if created: UserProfile.objects.create(user=instance)post_save.connect(create_user_profile, sender=User)
把UserProfile添加到admin

from django.contrib import adminfrom django.contrib.auth.admin import UserAdminfrom django.contrib.auth.models import Userfrom my_user_profile_app.models import UserProfile# Define an inline admin descriptor for UserProfile model# which acts a bit like a singletonclass UserProfileInline(admin.StackedInline): model = UserProfile can_delete = False verbose_name_plural = 'profile'# Define a new User adminclass UserAdmin(UserAdmin): inlines = (UserProfileInline, )# Re-register UserAdminadmin.site.unregister(User)admin.site.register(User, UserAdmin)
匿名用戶
我們來(lái)看一下匿名用戶的屬性,是對(duì)用戶的一個(gè)補(bǔ)充

class AnonymousUser(object): id = None username = '' is_staff = False is_active = False is_superuser = False _groups = EmptyManager() _user_permissions = EmptyManager()
web請(qǐng)求中的認(rèn)證
前面我們只是談到了操縱認(rèn)證相關(guān)對(duì)象的底層的APIs,在更高的層次,django可以把認(rèn)證框架鉤進(jìn)請(qǐng)求對(duì)象request系統(tǒng)中
首先,安裝會(huì)話中間件和認(rèn)證中間件(在MIDDLEWARE_CLASSES)里面添加sessionMiddleware和AuthenticationMiddleware,安裝好這兩個(gè)中間件后,你可以在視圖函數(shù)里面是用request.user(代表當(dāng)前已經(jīng)登陸的user對(duì)象,如果用戶還沒(méi)等,將代表一個(gè)匿名對(duì)象),可以使用is_authencated()方法來(lái)辨別是否已經(jīng)登陸
如何登陸用戶
django提供了兩個(gè)函數(shù)django.contrib.auth:authenticate()和login()
authentecate()
用給定的用戶名和密碼去認(rèn)證,返回一個(gè)User對(duì)象或者None

from django.contrib.auth import authenticateuser = authenticate(username='john', password='secret')if user is not None: if user.is_active: print "You provided a correct username and password!" else: print "Your account has been disabled!"else: print "Your username and password were incorrect."
login()
在視圖函數(shù)中可以使用login()方法去登陸一個(gè)用戶,這個(gè)方法需要一個(gè)HttpRequest對(duì)象和一個(gè)User對(duì)象,login()函數(shù)把用戶ID存在session里面(是用django的session框架,所以請(qǐng)確保啟用了會(huì)話中間件),如果是手工登陸用戶,請(qǐng)先條用authenticate()方法

from django.contrib.auth import authenticate, logindef 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.
如何注銷(xiāo)用戶
logout()
去注銷(xiāo)一個(gè)使用django.contrib.auth.login()方法登陸的用戶,請(qǐng)使用在視圖函數(shù)中使用django.contrib.auth.logout()方法注銷(xiāo),該方法需要一個(gè)HttpRequest對(duì)象并且沒(méi)有返回值
from django.contrib.auth import logoutdef logout_view(request): logout(request) # Redirect to a success page.限制登陸用戶的訪問(wèn)
原始方法
在視圖函數(shù)中檢查request.user.is_authencated()是否為真,從而決定是重定向到一個(gè)登陸頁(yè)面或者是錯(cuò)誤頁(yè)面
login_required裝飾器
decorators.login_required([redirect_field_name=REDIRECT_FIELD_NAME,login_url=None])
作為一個(gè)快捷方式,可以直接使用login_required()裝飾器
from django.contrib.auth.decorators import login_required@login_requireddef my_view(request):這個(gè)裝飾器按照以下步驟:
如果用戶沒(méi)有登陸,重定向到settings.LOGIN_URL(把在查詢(xún)字符串中的當(dāng)前絕對(duì)路徑傳參過(guò)去,例如/accounts/login/?next=/polls/3/如果用戶已經(jīng)登陸,正常執(zhí)行視圖函數(shù)默認(rèn)情況下,用戶在成功認(rèn)證后的重定向路徑被存在查詢(xún)字符串中的next參數(shù)中,如果你想修改的話,請(qǐng)使用redirect_field_name參數(shù)@login_required(redirect_field_name='my_redirect_field')
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注