I am building an account settings page. I was thinking of having a few routes that only accept post request then edit the records and then go back the account settings page.
The problem is that there is two account settings pages. One for users and one for an admin account.
The admin account_settings can use the same logic form the user account settings routes but If i use and post to use the user/account-settings route it returns back the user/account-settings route insted of the admin/user-account settings.
I was wondering how can flask returns back to the page it was on.
People usually solve this problem with session cookies (which you should have access to given that the user will be logged into an admin panel).
This is of course safter than using HTTP_REFERER (header sent by the client), as you control the contents of the session cookie entirely.
You could also pass a ?continue=http://... thing in the URL.
request.referrer will return back to the previous page. http://flask.pocoo.org/docs/0.11/reqcontext/
Related
We're using flask-login to handle logins to our webpage. We expect it to be very strict with sessions so when a browser is closed, the user is prompted to log back in again.
We expect user would be sent to the login page for every url, and the session won't persist.
We require strict protection
login_manager.session_protection = "strong"
login_manager.refresh_view = "users.login"
Refresh view is used as the docs state:
refresh_view
The name of the view to redirect to when the user needs to reauthenticate
When the user closes their browser and begins a new session, they are not prompted to login, instead they're given a page where href's redirect to the login page, and other links give permission errors. This isn't optimal.
Internally, the way redirects are accomplished is with flask_login is by using the unauthorized() function in the login_manager.py file, which uses the request library to grab the request url of the page the user is trying to access. When an user is logged out trying to access the page it will properly grab the correct url and redirect the user to the variable assigned to the login_view setting. However, when session protection is set to strong and the user quits the application and redirects to the page, the unauthorized() function is not being executed.
So why aren't they sent to the login page every new browser instance?
In our case, the user still had a remember me cookie that persisted the session. After adding this line
REMEMBER_COOKIE_DURATION = timedelta(minutes=0)
The user is correctly sent to the login page.
I am using flask security for authentication what i want is when user access to a specific url without login/access then it redirects to login page but it redirects to home page.
I know if i add
#login_required
decorator then it will redirect to login page but how to do without that decorator.
i.e
#app.route('/result')
#roles_accepted('admin')
def result():
//some code
I read from flask documentation to add this in app config file.
SECURITY_UNAUTHORIZED_VIEW = '/login'
but again it does not redirect to login page.
Can anyone guide me what i am doing wrong here.
Flask-Security integrates a number of other extensions into a neat package, so it is possible to utilize those packages independently of Flask-Security if necessary.
If you've installed Flask-Security, you should also have Flask-Login installed as a dependency. You can use the current_user class from Flask-Login to check for authentication and redirect manually:
from flask import redirect
from flask_login import current_user
#app.route('/result')
#roles_accepted('/admin')
def result():
if not current_user.is_authenticated:
return redirect(url_for('.login'))
else:
some code....
I'm not sure how this will play with #roles_accepted, but based on the source code it looks like this decorator will intervene prior to the result function if an inappropriate role is used and handle it with the security_unauthorized_callback.
This actually seems to be similar to what #login_required does, i.e. call the security_unauthorized_callback function when the specified conditions are not met, in this case, the proper roles.
If I understand the #roles_required decorator correctly, the above solution should prevent any authenticated users of the improper role from accessing the results page, then manually redirect any unauthenticated users who make it past that check, without using the #login_required decorator.
What is happening is correct.
SECURITY_UNAUTHORIZED_VIEW = '/login'
Redirects the user to the login view, however, what appears to be happening is you have an authenticated user who is not authorized to access the view. When you redirect to the login page, since the user is already authenticated, another redirect happens to the SECURITY_POST_LOGIN_VIEW which in your case is home page.
I have two suggestions.
1) If unauthorized user attempts to access the protected view, log them out and add a flash message that they need to login as authorized users (that is assuming your SECURITY_POST_LOGOUT_VIEW is /login). In this case, your configuration becomes
SECURITY_UNAUTHORIZED_VIEW = '/logout'
and will achieve your objective of having the user redirected to the login page. This happens even if the current user is not authenticated (ie is anonymous/ not logged in)
2) Instead of logging out the user, retain the redirect to home page and add a flash message asking the user to login as an authorized user to access the resource
I have been doing the Flask Web Development Book by Miguel Grinberg, and just finished up with the authorization blueprint. Though, I am having an issue that if I am already logged in, I can still put the url of the login page and go there. How can I prevent this in Flask?
While using Django, I came up with django-braces library which helps to do this, any such alternative available in Flask?
Redirect users who are logged in navigating to the login page.
To check if they are already logged in, examine the current_user proxy. Note that logged-in users will have current_user.is_authenticated() equal True, while users who aren't logged in will have the method return False.
You have two options for the destination: back to their previous page with redirect(request.referrer) or to one of your other pages with redirect(url_for('view_name')).
Use current_user.is_authenticated().
I am trying to develop login page for a web site. I am using Django 1.4.2. I stored users which logged on correctly to a cookie using set_cookie. But I didn't find clear_cookie in Django's documentation. How to clear a cookie to make a user log out?
Setting cookies :
def login(request):
response = HttpResponseRedirect('/url/to_your_home_page')
response.set_cookie('cookie_name1', 'cookie_name1_value')
response.set_cookie('cookie_name2', 'cookie_name2_value')
return response
Deleting cookies :
def logout(request):
response = HttpResponseRedirect('/url/to_your_login')
response.delete_cookie('cookie_name1')
response.delete_cookie('cookie_name2')
return response
You can simply delete whatever you've stored in the cookie - this way, even though the cookie is there, it no longer contain any information required for session tracking and the user needs to authorize again.
(Also, this seems like a duplicate of Django logout(redirect to home page) .. Delete cookie?)
So currently I'm using #login_required to block certain pages from users and redirect them, telling them they need to log in. but what I can't understand is how do I "let them" go to the page they were trying to go to once they log in. Currently I'm just using a typical render_to_response('with a certain view') but what if i want that response to be anywhere where they were trying to access. How do i code that?
The #login_required will generally pass you back the redirect_field_name (default is "next") for example: /accounts/login/?next=/polls/3/. So in your login view after authenticating and logging in the user you can do something like
response = HttpResponseRedirect(next)
# Do whatever else you need to do here with the response object
return response
See the docs at https://docs.djangoproject.com/en/1.3/topics/auth/#the-login-required-decorator
You can pass a url parameter back to your login page and use that to direct the user once they complete the login successfully.
from the login requiered decorator docs it says:
By default, the path that the user should be redirected to upon
successful authentication is stored in a query string parameter called
"next".
and usually when the login is done it take to the "next" url
Here's what django.contrib.auth.views.login does:
If called via GET, it displays a login form that POSTs to the same
URL. More on this in a bit.
If called via POST, it tries to log the
user in. If login is successful, the view redirects to the URL
specified in next. If next isn't provided, it redirects to
settings.LOGIN_REDIRECT_URL (which defaults to /accounts/profile/). If
login isn't successful, it redisplays the login form.