Fehler: CRSF verification..oder HttpResponse has no ..lower

Django, Flask, Bottle, WSGI, CGI…
Antworten
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

Hi,

ich mach irgendwas falsch. Weiss aber nicht was.

Code: Alles auswählen

from django.shortcuts  import render_to_response
from django.core.context_processors import csrf
from django.http import HttpResponse
from django.conf import settings
from models import User


def set_cookie(response, key, value):
    max_age = 5*24*60*60  #five days
    expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age), "%a, %d-%b-%Y %H:%M:%S GMT")
    response.set_cookie(key, value, max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, secure=settings.SESSION_COOKIE_SECURE or None)
    return response


def sysbioPortalStartApp(request):
    c={}
    c.update(csrf(request))

    if request.method == 'POST':
        if 'id' in request.COOKIES:
            return render_to_response('dolleSeite1.html',c)

        if request.POST.has_key('formid'):

            if request.POST['FormID] == 'LoginForm':
                errors=[]
                n=User.objects.filter(Name__exact=request.POST['username']).count()
                if n == 0:
                   userRowSet=User()
                   userRowSet.Name=request.POST['username']
                   userRowSet.Password=request.POST['password']
                   userRowSet.save()
                   response=render_to_response('portal.html',c)
                   response.set_cookie(response, 'id', 'ich')
                   return response
                elif n == 1:
                   errors.append('Der Anwender existiert schon.')
                   return render_to_response('index.html',{'errors':errors, '':c})

            elif  request.POST['FormID'] == 'dataForm1ID':
                return HttpResponse("Dolle Hauptseite!!!!!")
        else:
            return HttpResponse("Debug:nix Formular")

    return render_to_response('index.html',c)


Gruss FRanky
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

FrankTheFox hat geschrieben:ich mach irgendwas falsch. Weiss aber nicht was.
Aktuell machst du folgendes falsch:
  • Du setzt den Code hier nicht in Python-Tags.
  • Du sagst nicht was du als Ergebnis erwartest.
  • Du gibst keine detaillierte Fehlermeldung an.
So ist es nicht gerade einfach dir Hilfe zu leisten. Ins Blaue hinein (davon ausgehend, dass du Django 1.3 verwendest): Hast du vergessen {% csrf_token %} im Template zu verwenden?
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

Hi,

ja stimmt. Ich möchte in einer Anmeldeseite den Usernamen und das Password in einer MySQL-DB Tabelle speichern und einen Cookie setzen.
Was ich denke was der Code macht:
- Wenn ich die Anmeldeseite aufrufe wird sie angezeigt.

- Sobald ich auf "Send" klicke werte ich in in der Funktion den request aus.
ich setzte das Token neu ( update)

- in den Templates ist {% csrf_token %} enthalten.
Ich übergebe ich das Token "c" jeweils der index.html und dolleSeite.html.

- Wenn Formular abgeschickt befinde ich mich auf xxx.xxx.xxx.xxx/#
a) und erhalte den Fehler: CRSF verification failed.
In diesem Fall wird der User nicht in die DB geschrieben.
b) oder aber User ist in DB und ich erhalte.. HttpResponse has no attr 'lower'



Gruß
Franky
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

FrankTheFox hat geschrieben:

Code: Alles auswählen

        if request.POST.has_key('formid'):

            if request.POST['FormID] == 'LoginForm':
Hier stimmt etwas nicht. Das kann nicht der Code sein, der bei dir läuft.

Bekommst du wirklich einfach nur den Fehler "HttpResponse has no attr 'lower'"? Gibt es keinen Stacktrace, keine Zeilennummer, gar nichts?

Ich würde übrigens bei der Ausgabe der Templates den RequestContext verwenden. Dabei fällt im Code das manuelle Erzeugen und Übergeben des CSRF Tokens weg. Das Template-Tag muss natürlich weiterhin innerhalb der Form im HTML-Dokument stehen.

Code: Alles auswählen

from django.template import RequestContext
# ...
def show_me(request, foo_id):
    foo = get_object_or_404(Foo, pk=some_id)
    return render_to_response('foo.html', {'data': foo},
        context_instance=RequestContext(request))
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

Hi,

nein das mit FormID ist Quark. Ich hatte noch gedacht bom Posten Kommentare einzufügen und deshalb das wohl geändert. Da muss natürlich"formid" stehen.
AttributeError at /

'HttpResponse' object has no attribute 'lower'

Request Method: POST
Request URL: http://xxx.xxx.xxx.xxx/
Django Version: 1.2.4
Exception Type: AttributeError
Exception Value:

'HttpResponse' object has no attribute 'lower'

Exception Location: /usr/local/lib/python2.6/Cookie.py in set, line 452
Python Executable: /usr/local/bin/python
Python Version: 2.6.6
Traceback:
Environment:

Request Method: POST
Request URL: http://xxx.xxx.xxx.xxx/
Django Version: 1.2.4
Python Version: 2.6.6
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'sysbioPortal']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/usr/local/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response
100. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
39. resp = view_func(*args, **kwargs)
File "/usr/local/lib/python2.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
52. return view_func(*args, **kwargs)
File "/usr/home/sysdev/sysbioPortalApp/sysbioPortal/views.py" in sysbioPortalStartApp
40. response.set_cookie(response, 'id', 'frank')
File "/usr/local/lib/python2.6/site-packages/django/http/__init__.py" in set_cookie
376. self.cookies[key] = value
File "/usr/local/lib/python2.6/Cookie.py" in __setitem__
587. self.__set(key, rval, cval)
File "/usr/local/lib/python2.6/Cookie.py" in __set
580. M.set(key, real_value, coded_value)
File "/usr/local/lib/python2.6/Cookie.py" in set
452. if key.lower() in self._reserved:

Exception Type: AttributeError at /
Exception Value: 'HttpResponse' object has no attribute 'lower'
Der Cookie der gesetzt wurde:
Name: csrftoken
Inhalt: e3231603e3f903eceda91caa4a1afc85
Host: xxx.xxx.xxx.xxx.xxx
Pfad: /
Senden für: Jeden Verbindungstyp
Gültig bis: Mi 15 Aug 2012 12:51:31 CEST

Wenn ich mir mal meinen Code ansehe, dann sind die Angaben innerhalb des Cookies aber nicht so wie ich das vorgebe...



Gruß
Franky
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

FrankTheFox hat geschrieben:

Code: Alles auswählen

File "/usr/home/sysdev/sysbioPortalApp/sysbioPortal/views.py" in sysbioPortalStartApp
  40.                    response.set_cookie(response, 'id', 'frank')
...
File "/usr/local/lib/python2.6/Cookie.py" in set
  452.         if key.lower() in self._reserved:

Exception Value: 'HttpResponse' object has no attribute 'lower'
In deinem sysbioPortal/views.py machst du was falsch, denn am Ende ist key == response und das ist wohl nicht so gewollt ;)

Ein Blick auf https://docs.djangoproject.com/en/1.3/r ... set_cookie verrät, das es so sein muß:

Code: Alles auswählen

HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
Also in deinem Fall vielleicht: response.set_cookie('id', 'frank')


Aber warum machst du den Login selbst? Warum nutzt du dazu nicht direkt Django: https://docs.djangoproject.com/en/1.3/topics/auth/ ?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

Danke für die rege Hilfe! Ja stimmt das...
jens hat geschrieben: In deinem sysbioPortal/views.py machst du was falsch, denn am Ende ist key == response und das ist wohl nicht so gewollt ;)

Ein Blick auf https://docs.djangoproject.com/en/1.3/r ... set_cookie verrät, das es so sein muß:

Code: Alles auswählen

HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
Also in deinem Fall vielleicht: response.set_cookie('id', 'frank')
response-Objekt hat da nichts verloren.
jens hat geschrieben: Aber warum machst du den Login selbst? Warum nutzt du dazu nicht direkt Django: https://docs.djangoproject.com/en/1.3/topics/auth/ ?
Naja, weil ich dachte so den Code für das Anmelden selbst kontrollieren zu können und um mehr Kontrolle über die Vorgänge zu haben.
(Also nicht das ich ein Kontrollfreak wäre...).


Ich weiss, das hat jetzt nichts mit dem Problem zu tun, aber ich frage mich wie ich es anstelle, das wenn ich mich anmelde und z.B. den Usernamen im Cookie speichere, mich oder den User identifizieren kann. Das "csrf-Token" wird ja bei jedem neuen Request neu gebildet (update). Irgendwie mache ich ja nichts mit dem Token außer es in die Anmeldeseite zu integrieren. Das ist doch nicht der Sinn des Tokens.


Gruß
Franky
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

Hi,

ok, wenn ich wach gewesen wäre dann wäre mir sicher aufgefallen, dass..

Code: Alles auswählen

response=set_cookie( response, 'id', 'frank') 
es nur so geht, wenn ich denn schon meinen Cookie setzen möchte.

mit Funktion...

Code: Alles auswählen

def set_cookie(response, key, value):
    max_age = 5*24*60*60  #five days
    expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age), "%a, %d-%b-%Y %H:%M:%S GMT")
    response.set_cookie(key, value, max_age=max_age, expires=expires, path='/')                                                                                      
    return response
Eigentlich soll der Cookie fünf Tage gültig sein. Ist er aber nicht. Funktionieren max_age=max_age, expires=expires, nicht?
Chrome sagt über meinen Cookie:
Name: id
Content:
frank
Domain: xxx.xxx.xxx.xxx
Path: /
Send For: Any kind of connection
Created: Thursday, August 18, 2011 11:16:40 PM
Expires: When I close my browser
Tjo

Gruss
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

Jo,

Code: Alles auswählen

import datetime



def set_cookie(response, key, value):
    _max_age = 5*24*60*60  #five days
    _expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=_max_age), "%a, %d-%b-%Y %H:%M:%S GMT")
    response.set_cookie(key, value, max_age=_max_age, expires=_expires, path='/')
    return response


funzt!
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

FrankTheFox hat geschrieben:Naja, weil ich dachte so den Code für das Anmelden selbst kontrollieren zu können und um mehr Kontrolle über die Vorgänge zu haben.
(Also nicht das ich ein Kontrollfreak wäre...).
Das ist ein Full-Featured-Framework wie Django vielleicht nichts für dich. Warum sollte man auch vorhandene Features nicht zurückgreifen? Denkst du in Django wird schmu gemacht, oder was?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

jens hat geschrieben: Das ist ein Full-Featured-Framework wie Django vielleicht nichts für dich. Warum sollte man auch vorhandene Features nicht zurückgreifen? Denkst du in Django wird schmu gemacht, oder was?
Nein, natürlich nicht.

Also grob mein Problem:
ich möchte das der User sich anmeldet. Kein User in der DB -> Cookie. Wenn User schon da, aber kein Cookie -> Cookie neu.
Zeit des Cookies abgelaufen -> Cookie löschen und User löschen.

Wenn der User über Tabs browsed wird der Cookie vom Browser nicht gelöscht, also dachte nutze ich eine Session. Die befindet sich auf dem Serverrechner und wenn ich das
Expire-Datum mit der User id vergleiche, dann lösche ich die Session und den User, egal ob der Cookie noch exisitert.

Code: Alles auswählen

 s=SessionStore()
 _max_age = 5*24*60*60  #five days
 s.set_expiry(datetime.datetime.utcnow() + datetime.timedelta(seconds=_max_age)))
 s.save() 

was aber macht...

Code: Alles auswählen

 request.session['id'] =  userRowSet.Name
 request.session.set_expiry(5*24*60*60)
Gruß
Franky
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich verstehe ehrlich nicht, was du damit Lösen willst. Erzähl doch mal näher dein eigentliches Problem und warum der normale Django Login/Session-Handling dafür nicht funktioniert...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
FrankTheFox
User
Beiträge: 13
Registriert: Montag 18. Juli 2011, 11:37

Ok,

wenn der Anwender auf die URL in den Browser eingibt, dann kommt er (weil noch kein Cookie, mit was auch immer da drin steht) zu einer Registrationsseite. Hier gibt er Username und Password an.
In der Datenbank wird der Anwender in einer Tabelle mit id, username, password (derzeit md5) und expiredate gespeichert.
Cookie wird gechrieben. Immer wenn der Anwender jetzt die URL aufruft, dann wird der cookie gelesen und mit dem DB-Eintrag verglichen. Wenn noch Zeit, dann sieht er sofort eine Seite mit der er arbeiten kann (sind eigentlich mehrere aber egal) Zeitspanne abgelaufen, sagen wir mal 4 Wochen, dann hat er noch 2 Tage Zeit kann sich seine Texte, oder was auch immer er erstellt hat downloaden oder was auch immer.


Gruß
Franky
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ja, aber das ist doch genau das selbe, was der Django Login macht. :K

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten