Search code examples
djangoauthenticationregistrationdjango-registration

Django-registration setup without password


I am trying to make a website, where people only put their email addresses and they are logged in with cookies and all. At a later stage, i will ask them provide password and names, but NO username will be used. I am trying to do this with django-registraition, but i get errors and i have a few problems.

First to disable usernames as a login feature, i put str(time()) instead of username - i was looking for something that will change every time.

However, when I skip the authentication (which i currently don't need) i get error:

'RegistrationProfile' object has no attribute 'backend'

Alternatively, i can leave the authentication but then i don't know how to authenticate it only with email and no password. Also, i don't know how to make the next line work:

auth.login(request, ProfileUser)

If anyone can get me out of here, it would be awesome. Here is some code:

my form Class:

class RegistrationFormCustom(forms.Form):
email = forms.EmailField()
def do_save(self):
    new_u = User(username=str(time()),email= self.cleaned_data.get('email'),)
    new_u.save()
    new_p = Profile.objects.create_profile(new_u)
    new_p.save()
    return new_p

my view:

def registerCustom(request, backend, success_url=None, form_class=None,
         disallowed_url='registration_disallowed',
         template_name='registration/registration_form.html',
         extra_context=None,
     initial={}):

form = RegistrationFormCustom(initial=initial)
if request.method == 'POST':
    form = RegistrationFormCustom(initial=initial, data=request.POST)
    if form.is_valid():
        profile = form.do_save()
        profile = auth.authenticate(username = profile.user.email, password = form.cleaned_data.get('pass1'))
        print(profile)
        auth.login(request, profile)
        return redirect('/')

    else:
        pass

return render_jinja(request, 'registration/registration_form.html',
        type="register",
        form = form
        )

and i will post any other snipped required happily


Solution

  • You're getting the 'RegistrationProfile' object has no attribute 'backend' error because the user is not yet authenticated. To log someone in, you have to call the authenticate method first, which requires a password. So, what you can do instead, is this:

    from django.contrib.auth import load_backend, login, logout
    from django.conf import settings
    
    def _login_user(request, user):
        """
        Log in a user without requiring credentials (using ``login`` from
        ``django.contrib.auth``, first finding a matching backend).
    
        """
        if not hasattr(user, 'backend'):
            for backend in settings.AUTHENTICATION_BACKENDS:
                if user == load_backend(backend).get_user(user.pk):
                    user.backend = backend
                    break
        if hasattr(user, 'backend'):
            return login(request, user)
    

    Then, to log someone in, just call the _login_user function with the request and User model. (This will be profile.user in your case, probably) Do this instead of calling auth.login. I'm not sure on how you're going to determine whether this is a valid user or not, without a password or username, but I'll leave that to you. If you still have trouble, let me know.

    Short Explanation:

    What basically happens here is that Django requires a user to be authenticated in order to be logged in via the login function. That authentication is usually done by the authenticate function, which requires a username and password, and checks whether the supplied password matches the hashed version in the database. If it does, it adds an authentication backend to the User model.

    So, since you don't have a password and username, you just have to write your own method for adding the authentication backend to the User model. And that's what my _login_user) function does - if the user is already authenticated, it just calls login, otherwise, it first adds the default backend to the User model, without checking for a correct username and password (like authenticate does).