2013-08-29 4 views
24

Когда я создаю пользователя из django-admin, пароль пользователя зашифрован. , но когда я создаю пользователя из оболочки django, пользовательский пароль сохраняется в виде обычного текста. Пример:Как создать пользователя из оболочки django

{ 
    "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] пароль сохранен в виде простого текста. как отменить это поведение.

+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. Я даже не уверен, что прямое установление пароля через 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 из django-shell.

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

Это будет хранить зашифрованный пароль.

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

Это будет хранить зашифрованный пароль.

Но

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

Это будет хранить простой текстовый пароль. Не применяется хеширование/шифрование, поскольку вы изменяете свойство напрямую.

+1

'user = Пользователь (имя пользователя =" django ", password =" secret ")' будет ** не ** работать так, как вы ожидаете. Перед тем, как поделиться им, проверьте его. –

+0

Эй, я просто пропустил вызов save() после первого заявления. Здесь что-то еще не так? –

+1

Ваш первый и третий примеры приводят к бесполезному объекту пользователя. Только правильные пути для установки паролей для объекта Джанго пользователя являются: 1 - вызов 'set_password' на существующем объекте пользователя 2 - создание объекта пользователя с' User.objects.create_user' вспомогательной функцией С обоего этих методы, которые вы передаете в пароле в той же форме, что и аутентифицирующий пользователь, вводит его, гарантируя, что согласование хеша будет работать, когда они попытаются войти в систему. Если вы установили пароль, используя два других примера, пользователь никогда не будет способный войти в систему, поскольку проверка хеширования никогда не пройдет. –

0

Ответ для тех, кто использует Джанго 1.9 или выше, так как from django.contrib.auth.models import User устарел (возможно, даже раньше), но, безусловно, на 1,9.

Вместо делать: в Баш:

python manage.py 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, тип оболочки:

python manage.py createsuperuser 
1

Для автоматизации сценария вы можете использовать функцию pipe для выполнения списка команд без необходимости вводить его каждый раз.

// 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() 

Ref: 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')