On Tue, 2005-08-30 at 04:24 -0700, [EMAIL PROTECTED] wrote: > Hi All > > Just starting with django and have very quickly got to the point where > I can set out a simple little app. > > The next thing I need to be able to do is implement user > authentication. Nothing too fancy just a basic one log in and you can > do everything type set up. > > My question is what is the best way to go about this? Where should my > security checks go, in the view? in the model?
A little bit of both. I'm doing a multi-user feed reader right now (will be publicly released when I'm happy with it), so I've managed to get this working. Basically you want a user model that can handle its own authentication (it can be entirely database-backed, or it can be a cache of some other source, such as ldap). Then you need a login view, which will check authentication and if successful, store the user_id in the session, and you need something (probably a decorator) to check that the user is logged in where required. Here's the login-relevant stuff from my app; some of which is copied more-or-less-directly from django's admin framework: models/engulf.py: class User(meta.Model): username = meta.CharField('Username', maxlength=64, unique=True) password = meta.CharField('Password', maxlength=64) feed = meta.ManyToManyField(Feed, filter_interface=meta.VERTICAL, null=True, blank=True) class META: admin = meta.Admin() def __repr__(self): return self.username def check_password(self,password): if password == self.password: return True else: return False views/engulf.py: class LoginManipulator(formfields.Manipulator): def __init__(self): self.fields = ( formfields.TextField(field_name="username", length=30, maxlength=64, is_required=True, validator_list=[self.check_login]), formfields.PasswordField(field_name="password", length=30, maxlength=64, is_required=True), ) def check_login(self, field_data, all_data): username = all_data['username'] password = all_data['password'] try: u = users.get_object(username__exact=username) if u.check_password(password): return True else: raise validators.ValidationError("Invalid username/password.") except users.UserDoesNotExist: raise validators.ValidationError("Invalid username/password.") def login(request): manipulator = LoginManipulator() if request.POST: new_data = request.POST.copy() errors = manipulator.get_validation_errors(new_data) if not errors: # successful login u = users.get_object(username__exact=request.POST['username']) request.session['user_id'] = u.id if request.GET: try: next = self.request.GET['next'] return HttpResponseRedirect(next) except KeyError: pass return HttpResponseRedirect('/engulf/') else: new_data = errors = {} form = formfields.FormWrapper(manipulator, new_data, errors) t = template_loader.get_template("engulf/login") c = Context(request, { 'form': form,} ) return HttpResponse(t.render(c)) def logout(request): try: del request.session['user_id'] except KeyError: pass manipulator = LoginManipulator() new_data = errors = {} form = formfields.FormWrapper(manipulator, new_data, errors) t = template_loader.get_template("engulf/login") c = Context(request, { 'form': form, 'from_logout': "You have successfully logged out." } ) return HttpResponse(t.render(c)) And views/util.py: def redirect_to_login(next): "Redirects the user to the login page, passing the given 'next' page" response = HttpResponseRedirect('/engulf/accounts/login/?%s=%s' % (REDIRECT_FIELD_NAME, next)) response['Pragma'] = "no cache" response['Cache-Control'] = "no-cache" return response # decorators def login_required(view_func): """ Decorator for views that checks that the user is logged in, redirecting to the log-in page if necessary. """ def _checklogin(request, *args, **kwargs): try: user_id = request.session['user_id'] u = users.get_object(id__exact=user_id) if user_id: return view_func(request, *args, **kwargs) else: return redirect_to_login(request.path) except (KeyError, users.UserDoesNotExist): return redirect_to_login(request.path) return _checklogin A typical view function will be decorated with login_required like so (as I'm using python 2.3): def view(req): blah blah blah... view = util.login_required(blah) > Anyone point me in the right direction? Or even a breif explanation of > how django's admin authentcation works might get me going. I arrived at this solution by looking at the anonymous session documentation and the admin code. If my code samples don't help, you might want to look there, too. Good luck! -- +----------------------------------------------------------------+ | Jason F. McBrayer [EMAIL PROTECTED] | | "If you wish to make Pythocles wealthy, don't give him more | | money; rather, reduce his desires." -- Epicurus |