By default the decorator #permission_required($SOME_PERMISSION), checks if the requesting user has the required permission to request this view or not , if it doesn't, it's redirected to the login page or any other specified page.(e.g. if the user is not logged in he's redirected to the login page).
Here's my problem , i want to redirect a not logged in user to the login page, but there might be a logged in user that doesn't have the required permission, by default that user is being redirected to the login page and well he's already logged in so , he's redirected again to the page he had requested and here happens a loop.
So what i want to do is to change the behavior of this decorator (write an equivalent code in my view function instead of using #permission_required) to check whether the user can't see the requested page cause he's not logged in , or he is logged in but doesn't have the permission, and then redirect him accordingly to the correct page.
any help would be greatly appreciated :)
Thanks in advance
Just pass the login_url parameter to permission_required, like:
#permission_required($SOME_PERMISSION, login_url='/my/custom/page')
I think what you are looking for is this answer:
How can make Django permission_required decorator not to redirect already logged-in users to login page, but display some message
I hope that helps!
Related
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 am working on openedx and i'm creating a user_login api, that will login the user coming from a particular site.
I'm able to log in the user via
login(request,user) function and it's showing an output :
2016-06-30 01:57:23,361 INFO 5426 [audit] models.py:1805 - Login
success - chogath (chogath#leauge.com)
But when I login to the said login page from browser,it still shows the user not logged in, I was expecting to be redirected to the dashboard.
Am I missing something here? Any help would be appreciated, thanks .
Are you issuing a request explicitly after the login function? login will not create a response for you automatically, you have to do something like this. Use return redirect(...) or return render(...).
I have implemented User account management into my application using Django all-auth. I have enabled login using username and password as well as with facebook connect.
The problem goes like this:
1) User visits a page http://example.com/page1/ and clicks login
2) He's taken to http://example.com/accounts/login?next=/page1/
3) When the user logs in using username and password, the user is redirected back to http://example.com/page1. But if the user logs in with facebook, he's taken to homepage.
How can I get desired behavior with Facebook login too?
You need to override the get_login_redirect_url method of django-allauth.
For this inherit the DefaultAccountAdapter class as
from allauth.account.adapter import DefaultAccountAdapter
class MyAccountAdapter(DefaultAccountAdapter):
def get_login_redirect_url(self, request):
# get the next parameter from request object and return the url
And make changes on settings.py
ADAPTER = "APPNAME.FILENAME.MyAccountAdapter"
ACCOUNT_ADAPTER = "APPNAME.FILENAME.MyAccountAdapter"
This should work !
How are you generating the Facebook login link? Most likely you are not indicating the next parameter there. The allauth documentation gives this example:
Google
To get the proper next parameter you can access request.GET.next.
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.
I've a page at / that displays a form for signup new users.
When a new user registers, it will redirect to /dashboard.
But when an authenticated user go to /, it should see the /dashboard page.
The question is: should I put something like this in the home() view:
if request.user.is_authenticated():
return HttpResponseRedirect("/dashboard")
or this is an ugly method and should I return different templates from my home() relying on the user's auth status? In this case, how can I customize my URL to show /dashboard and not / ?
The redirect method is absolutely fine. Not sure what you mean by ugly. The redirect should take care of your URL issue as well.
If I understand you correctly, you have a "dashboard" which is available only for authenticated users, so if not logged in user tries to enter it, he should be redirected to the sign up form. Right?
Have you considered using middleware? Such middleware could check if the user is logged in and if not - return the sign up form view, otherwise continue processing the request, and return the home view. Read about process_request and process_view here.