I'm trying to create user sessions as explained here http://www.essentialtech.co.nz/content/using_session_google_app_engine_and_python_27 . Below is the Login page handler class. Everything is fine, but I'm not able to understand what the 'self.session.get('referrer')' would do. I googled for it and found that 'HTTP_REFERER' refers to the site url where you are coming from. But why do we need it in the Login handler here? I feel glad if some one can explain it to me.
class LogIn(BaseHandler):
def get(self):
if self.session.get('user'):
del self.session['user']
if not self.session.get('referrer'):
self.session['referrer'] = \
self.request.environ['HTTP_REFERER'] \
if 'HTTP_REFERER' in self.request.environ \
else '/'
template_values = {
}
template = jinja_environment.get_template('login.html')
self.response.out.write(template.render(template_values))
def post(self):
user = self.request.get('user')
self.session['user'] = user
logging.info("%s just logged in" % user)
self.redirect('/')
I presume it's used to know where to redirect the user after login. But the POST redirects to '/' so doesn't look like it's plugged in, at least not in this snippet. This doesn't make sense though, if you come in from a totally different website. So maybe it's just used for logging / tracking purposes. Again, not detailed in this snippet.
Related
class XX(MethodView):
def get(self):
....
def post(self):
error = None
user = request.form['username']
password = request.form['password']
print user,password
if user == 'xxx' and password == 'xx':
session['logged_in'] = True
session['session_user'] = 'xx'
return redirect("control")
else:
errors = []
errors.append("Login error")
return render_template("login.html" , errors=errors)
#adding rule for control Blueprint
control.add_url_rule("/control",view_func= ControlView.as_view('control'))
The code snippet checks for specific username,password and should redirect to a specific page.
When requested for the login page, a GET request is sent.The above snippet gets username and password and adds to session dictionary.The redirect method results in a POST request and response code is 302 FOUND followed by a GET request to desired page with 200 OK response code.
But the redirection does not happen, it remains on same login page.
what should redirect have as parameters?
redirect('control')
redirect(url_for('control'))
redirect(url_for('control.control'))
Why using render_template('XX.html') responds with 500 response code ??
Is this code inside of a blueprint named 'control'? I'm guessing yes, based on the code shown above.
When you're using blueprints, you cannot know the final URL (eg: /control) in advance, since the blueprint user can map the base URL anywhere they'd like.
The best way to redirect to your view, assuming this is a blueprint, is using the blueprint URL notation: redirect(url_for('control.control')).
If this is NOT going to be used in a blueprint, you should be able to do something like: redirect(url_for('control')) so long as that's your view name when added to the route.
Hope this was clear.
If you're still having errors when trying to two above examples, enable Flask debugging (app.config['DEBUG'] = True) and re-try. The traceback should explain what's happening in more depth.
I'm writing a web app which has a page for admin tasks. One of the tasks is that the admin users must be able to edit other users details. Alas, I've fallen at quite a simple roadblock.
I've set up a very simple jQuery AJAX Get request, successfully transferring a string to the server and back. This is just background, but not the issue. The issue lies in retrieving other user's objects.
At the moment, with a username I know exists, this code which is accessed in views.py, produces a 500 Internal Server Error.
#login_required
def user_edit_getuser(request):
# Like before, get the request's context.
context = RequestContext(request)
inputname = request.GET['inputNameSend']
user_obj = User.objects.get(inputname)
return HttpResponse(inputname) #later will return a JSON String
get takes keyword arguments only: the key is the field to look up.
user_obj = User.objects.get(username=inputname)
Also, you should probably deal with the possibility that the GET request has no inputNameSend key.
For JS development, you can usually see the error page in the Chrome dev tools/Firebug console in the Network tab.
Specifically, pages using an optional regular expression. By optional, I mean PAGE_RE below.
I am creating a Wiki. If a user searches a term, and that term doesn't already exist, then the user is redirected to an edit page so they can create the new content. This only happens, however, if the user is logged in. To determine if the user is logged in, I check for a cookie. If the user isn't logged in(no cookie), then I redirect, not to the edit page, to create the new content, but to the login page, dealt with by the Login class below. The user logs in, a cookie is created, and then they are redirected to the edit page to create the content they originally searched for. In order to remember what their topic was, so I can redirect after the login, I send the topic(in the form '/topic') to the Login class, where it's received as a parameter by the get and post methods. If a user just comes to the site and logs in normally, they are redirected to the home page, but in this case, because the topic has been received by get and post and is not None, I use the line self.redirect('/edit/%s' % topic[1:]) below, to send them on to their original destination. The problem is, css isn't working for the two urls in below that use PAGE_RE. JsFiddler4 shows that there is a 404 involving /login/css/wiki.css. It suddenly clicked after some time that that url is not the url for the login page when it receives the extra 'topic' param. It is also the case with EditPage. How can I get css to work on these pages/urls when they are sometimes different? I didn't know what was going on for ages, then I downloaded and ran JsFiddler4 and figured it out. I am using Google App Engine, webapp2, jinja2. Any help much appreciated. Apart from those two pages, css works fine.
This code is out of order and incomplete, but I hope it's sufficient
PAGE_RE = r'(/?(?:[A-Za-z0-9_-]+/?)*)'
app = webapp2.WSGIApplication([
('/signup', Register),
('/logout', Logout),
('/login' + PAGE_RE, Login),
('/edit' + PAGE_RE, EditPage),
('/', Front),
(PAGE_RE, WikiPage),
], debug=True)
class Login(Main):
""" Validate form and validate users cookie """
def get(self, topic):
self.render('login.html', error={})
def post(self, topic):
username = self.request.get('username')
password = self.request.get('password')
if not username or not self.valid(user=username):
self.login_error(user=username)
elif not password or not self.valid(pw=password):
self.login_error(user=username)
elif not self.user_exists(username):
self.render('login.html', error={'no_user':'That user does not exist'})
else:
self.login(username, password, topic=topic)
def login(self, name, pw, topic):
user_hash = User.get_user_hash(name)
if self.valid_pw(name, pw, user_hash):
self.create_secure_cookie('user_id', name)
if topic:
self.redirect('/edit/%s' % topic[1:])
else:
self.redirect('/')
else:
self.login_error(user=name)
def login_error(self, user):
self.render('login.html', username=user, error={'login': errors['login']})
def valid_pw(self, name, pw, user_hash):
salt = user_hash.split('|')[0]
return user_hash == self.create_user_hash(name, pw, salt)
Ok, I solved this. Here's what appeared to be happening.
This redirect was sending a parameter to the Login class above:
self.redirect('login/%s' % wiki_topic) #wiki_topic = something like 'topic'
when looking for the css for a page, what seems to happen is that the last part of the path up to the '/' is taken off, and replaced by the path to the css, '/css/wiki.css' in my case.
So I was passing 'login/topic' and just 'topic' was being replaced by the css path to give:
'login/css/wiki.css' instead of the correct just 'css/wiki/css'.
To stop this from happening, I changed the line redirecting to the Login class from:
self.redirect('login/%s' % wiki_topic) to >> self.redirect('login%s' % wiki_topic)
the second version has no slash before the %s.
here's my code
def subscribe_current_user(self):
user1 = SocialNodeSubscription(parent=self.key)
user1.subscribed = True
current_user = users.get_current_user()
logging.error(current_user)
if current_user:
user1.user=current_user
else:
raise users.UserNotFoundError
user1.put()
The problem is that get_current_user returns None even if i'm logged in. It stores a None in the field user1.user and it prints a None in the log console.
How can i solve that?
Do you have login: required defined in app.yaml for your handler or have you provided a login url using users.create_login_url() so that the user can explicitly login.
Even if you are logged into google somewhere, users.get_current_user() won't
return a user object.
I have seen a lot of similar questions.
It helps to think of this line differently...
user = users.get_current_user()
This line doesn't search high and low in your browser and cache and retrieve whatever info and put it into a nice user object; it simply checks if an user is logged in to the app using the users class. Which means if you did not have the user logged with the users class, chances are this line of code won't do what you want it to do.
The important codes that should usually follow a get_current_user() method:
if user:
greeting = ('Welcome, %s! (sign out)' %
(user.nickname(), users.create_logout_url('/')))
else:
greeting = ('Sign in or register.' %
users.create_login_url('/'))
self.response.out.write('<html><body>%s</body></html>' % greeting)
I believed, you surely importing this,
from google.appengine.api import users
And also, Are you really authenticating django's 'User' model at the time of login?
Im checking the examples google gives on how to start using python; especifically the code posted here; http://code.google.com/appengine/docs/python/gettingstarted/usingdatastore.html
The thing that i want to lean is that, here:
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/')
They are saving a comment, IF the user is logged in, we save the user; if not its empty and when we get it out of the db we actually check for that here:
if greeting.author:
self.response.out.write('<b>%s</b> wrote:' % greeting.author.nickname())
else:
self.response.out.write('An anonymous person wrote:')
So what i would like is to use the User object to get the information, like this:
class Guestbook(webapp.RequestHandler):
def post(self):
user = users.get_current_user()
if user:
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/')
else:
self.redirect(users.create_login_url(self.request.uri))
So, what i would like to do with that code is to send the user to the login url(if he is not logged in); and then to come back with whatever he had in post and actually post it. But what happens is that it doesnt even get to that action coz is nothing in the post.
I know i could put something in the session and check for it in the get action of the guestbook, but i wanted to check if someone could come up with a better solution!
Thanks
The problem is, self.redirect cannot "carry along" the payload of a POST HTTP request, so (from a post method) the redirection to the login-url &c is going to misbehave (in fact I believe the login URL will use get to continue when it's done, and that there's no way to ask it to do a post instead).
If you don't want to stash that POST payload around somewhere (session or otherwise), you can make your code work by changing the def post in your snippet above to def get, and of course the action="post" in the HTML written in other parts of the example that you haven't snipped to action="get". There are other minor workarounds (you could accept post for "normal" messages from logged-in users and redirect them to the get that perhaps does something simpler if they weren't logged in yet), but I think this info is sufficient to help you continue from here, right?