2013-08-29 28 views
24

當我從django-admin創建用戶時,用戶密碼被加密。 但是當我從django shell創建用戶時,用戶密碼保存爲純文本。 例子:如何從django shell創建用戶

{ 
    "date_joined": "2013-08-28T04:22:56.322185", 
    "email": "", 
    "first_name": "", 
    "id": 5, 
    "is_active": true, 
    "is_staff": false, 
    "is_superuser": false, 
    "last_login": "2013-08-28T04:22:56.322134", 
    "last_name": "", 
    "password": "pbkdf2_sha256$10000$iGKbck9CED0b$6hWrKYiMPNGKhcfPVGal2YP4LkuP3Qwem+2ydswWACk=", 
    "resource_uri": "/api/v1/user/5/", 
    "username": "user4" 
}, 
{ 
    "date_joined": "2013-08-29T01:15:36.414887", 
    "email": "[email protected]", 
    "first_name": "", 
    "id": 6, 
    "is_active": true, 
    "is_staff": true, 
    "is_superuser": true, 
    "last_login": "2013-08-29T01:15:36.414807", 
    "last_name": "", 
    "password": "123test", 
    "resource_uri": "/api/v1/user/6/", 
    "username": "test3" 
} 

我試圖讓REST風格的API一個簡單的博客應用: 當我嘗試[通過傳遞JSON]密碼插入由POST請求用戶保存爲純文本。 如何覆蓋此行爲。

+0

你是如何把JSON到數據庫? –

+0

我正在使用django-tastypie。 – shifu

回答

65

您不應該通過正常的User(...)語法創建用戶,添加其他人的建議。您應該始終使用User.objects.create_user(),它會妥善設置密碼。

[email protected]> manage.py shell 
>>> from django.contrib.auth.models import User 
>>> user=User.objects.create_user('foo', password='bar') 
>>> user.is_superuser=True 
>>> user.is_staff=True 
>>> user.save() 
+0

請閱讀下面的代碼的完整問題 – shifu

+2

我不明白你的「完整問題」與我的答案是否有衝突。如果你需要在代碼中創建一個用戶,你應該使用'User.objects.create_user()'。 –

+7

這個神奇的用戶對象來自哪裏? H8代碼樣本在沒有關鍵的「進口」位的情況下給出。 'django.contrib.auth.models' –

3

您使用user.set_password在django shell中設置密碼。我甚至不確定是否通過user.password直接設置密碼甚至可以正常工作,因爲Django希望密碼的散列。

password字段不存儲密碼;它將它們存儲爲<algorithm>$<iterations>$<salt>$<hash>,所以當它檢查密碼時,它會計算散列並進行比較。我懷疑用戶實際上是否有密碼,其計算密碼哈希值是<algorithm>$<iterations>$<salt>$<hash>表單。

如果你能夠創建用戶所需的所有信息得到json,你可以只是做

User.objects.create_user(**data) 

假設你通過JSON稱爲數據。

注意:如果您在data中有額外或缺失的項目,這將引發錯誤。

如果你真的想覆蓋此行爲,你可以做

def override_setattr(self,name,value): 
    if name == 'password': 
     self.set_password(value) 
    else: 
     super().__setattr__(self,name,value) #or however super should be used for your version 

User.__setattr__ = override_setattr 

我沒有測試過該方案,但它應該工作。使用風險自負。

+0

也許我需要覆蓋用戶這樣做的默認保存。 – shifu

+0

我不認爲你應該這樣做,因爲它是默認的用戶對象(意思是說,如果你這樣做了,它會使用戶使用其他人,除非你被分類)。使用'set_password'有什麼問題? –

+0

sry,但我對原始問題進行了一些更改,以使其與我所做的更相關。 – shifu

-6

有幾種方法可以從django-shell爲django用戶對象設置密碼。

user = User(username="django", password = "secret") 
user.save() 

這將存儲加密的密碼。

​​

這將存儲加密的密碼。

但是,

user = User(username="django") 
user.password="secret" 
user.save() 

這將存儲明文密碼。由於您直接修改屬性,因此不會應用散列/加密。

+1

'用戶=用戶(用戶名=「的Django」,密碼=「祕密」)'會不會** **工作像您期望的。請在分享之前核實建議。 –

+0

嘿,我剛剛在第一個聲明後錯過了調用save()。這裏還有什麼不對嗎? –

+1

您的第一個和第三個示例會導致無用的用戶對象。唯一正確的方法來設置密碼爲Django的User對象是: 1 - 調用'set_password'現有用戶對象 2 - 用'User.objects.create_user'輔助函數 與這兩個創建用戶對象你傳遞方法在同一形式的認證用戶將輸入該密碼,確保hash匹配將工作時,他們接下來嘗試登錄。 如果設置使用兩個例子一個密碼,用戶絕不會能夠登錄,因爲哈希檢查將永遠不會通過。 –

0

答案使用Django 1.9或更大的那些自from django.contrib.auth.models import User已被棄用(甚至可能更早),但肯定了1.9。

而是做: 在bash:

python manage.py shell 

在Python Shell中創建用戶與密碼:

from django.apps import apps 
User = apps.get_model('user', 'User') 
me = User.objects.create(first_name='john', email='[email protected]') # other_info='other_info', etc. 
me.set_password('WhateverIwant') # this will be saved hashed and encrypted 
me.save() 

如果從一個API來你應該申請一個形式,這樣的:

import json 
User = get_model('User') 
class UserEditForm(BaseModelForm): 
     """This allows for validity checking...""" 

     class Meta: 
      model = User 
      fields = [ 
       'first_name', 'password', 'last_name', 
       'dob', # etc... 
      ] 
# collect the data from the API: 
post_data = request.POST.dict() 
data = { 
'first_name': post_data['firstName'], 
'last_name': post_data['firstName'], 
'password': post_data['password'], etc. 
} 
dudette = User() # (this is for create if its edit you can get the User by pk with User.objects.get(pk=kwargs.pk)) 
form = UserEditForm(data, request.FILES, instance=dudette) 
if form.is_valid(): 
    dudette = form.save() 
else: 
    dudette = {'success': False, 'message': unicode(form.errors)} 
return json.dumps(dudette.json()) # assumes you have a json serializer on the model called def json(self): 
+0

請注意,官方文檔(https://docs.djangoproject.com/en/1.10/topics/auth/default/#creating-users)從'django.contrib.auth.models'中導入用戶模型。通過你的'other_info' kwargs來判斷,你可能想提到你的例子使用了一個自定義的用戶模型。 – Escher

+0

這是爲了說明的目的,因爲可以隨意將您的特定用戶模型的任何信息放在此處......但確定某人是否真的具有「other_info」,必須是自定義用戶模型。 – Zargold

1

爲django創建超級用戶的最快方法是輸入shell:

python manage.py createsuperuser 
1

要使腳本自動化,您可以使用管道功能來執行命令列表,而不必每次輸入它。

// content of "create_user.py" file 
from django.contrib.auth import get_user_model 

# see ref. below 
UserModel = get_user_model() 

if not UserModel.objects.filter(username='foo').exists(): 
    user=UserModel.objects.create_user('foo', password='bar') 
    user.is_superuser=True 
    user.is_staff=True 
    user.save() 

編號:get_user_model()

記得先激活VIRTUALENV,然後在下面(Linux)的運行命令:如果您在使用窗口

cat create_user.py | python manage.py shell 

然後用替代命令類型命令

type create_user.py | python manage.py shell 

或兩者兼有Linux和Windows

# if the script is not in the same path as manage.py, then you must 
# specify the absolute path of the "create_user.py" 
python manage.py shell < create_user.py 
0

創建用戶執行:

$ python manage.py shell 
>>>> from django.contrib.auth.models import User 
>>>> user = User.objects.create_user('USERNAME', 'MAIL_NO_REQUIRED', 'PASSWORD')