How to add Flask-JWT-Extended error handlers to Flask-Restx? - python

I'm trying to add a Flask-JWT-Extended specific error handler to Flask-Restx. In particular, I'm trying to add #jwt.expired_token_loader. I need to display templates to users in my API and for that I need to save the users information in their browser.
#jwt.expired_token_loader
#jwt_required(refresh=True)
def refresh_cookie_handler(jwt_header, jwt_payload):
return render_template("/refresh_cookie/index.html")
When the cookie/ token is expired, it just does nothing. The handler works on the normal Flask routes, like app.route().

Related

Login-error page not displayed when using python-social-auth

I am using social-app-django (part of python-social-auth) to implement Facebook login for the users of my Django site. I have a requirement that users must be found in the local user database before they can log in with Facebook. I have replaced the auth_allowed-part of the authentication pipeline, to perform this check:
def auth_allowed(backend, details, response, *args, **kwargs):
if not backend.auth_allowed(response, details) or not is_registered_user(response, details):
raise AuthForbidden(backend)
where is_registered_user() is a custom function that checks whether the user exists locally.
My problem is that the users are not redirected to the login error URL, if this check fails and the AuthForbidden exception is thrown. Instead, the site returns a 500.
The error-page URL is configured as follows in settings.py:
LOGIN_ERROR_URL = "/"
I am using Django CMS, so I have also tried implementing middleware that overwrites SocialAuthExceptionMiddleware (which is supposed to handle the AuthForbidden exception in a standard setup) to return a CMS-page instead of an URL from settings.py but this middleware is not invoked in the process, as far as I can see.
Any ideas on how to fix this? Am I missing some configuration?
I think I solved the problem: I accidentally used
social.apps.django_app.middleware.SocialAuthExceptionMiddleware
instead of
social_django.middleware.SocialAuthExceptionMiddleware
when referring to the exception-handling middleware. The bug was most likely introduced during an upgrade from django-social-auth to python-social-auth/social-app-django some time ago.

Require new login for each page view

I am currently using code found here:
http://flask.pocoo.org/snippets/8/
And I decorate my function accordingly to have the admin authenticate when requesting a specific admin page. However, instead of requiring the admin to keep authenticating each time they admin page, I noticed that it somehow keeps track of the session and no longer requires authentication after successfully authenticating once. Is there some way to force flask to re-authenticate every time an admin requests the given decorated admin page?
Using the included snippet, there is no good way to force a user to log in every time they request the given page.
This is because that snippet is using HTTP Basic Auth and there is no good way to ask the browser to stop sending that header.
What you are looking for can be done with a custom decorator. You can use the sample below. Note that your case will be different, but you can use this as a guide.
from web import app, has_role
#app.route("/admin/my_page")
#login_required
#has_role(role="admin")
def admin_my_page():
//do stuff
Then, in your project init, or an include file you can add the following:
def has_role(role=None):
def _initial_decorator(view_func):
def _decorator(*args, **kwargs):
response = view_func(*args, **kwargs)
if g.user.user_level != role:
from flask import redirect, url_for
return redirect(url_for("no_access"))
return response
return wraps(view_func)(_decorator)
return _initial_decorator
This should at lease give you an idea of how to create a custom decorator, and then check for role permissions. You can expand this to however you need. You can put engine logic, or other checks to fit your project.

Render Django view in new window

I have a Django view that I want to render in a new window when it is called from a python script outside of views.py. My questions are 1.Can I use a Django view from a python script in a subdirectory of my project that is outside the app where the view is located (view location: MyProject/Myapp/views.py and the python script location: MyProject/ProcessingCode/myscript.py)? 2. If that is possible, how do I render the view in a new window?
Django view that I want rendered in a new window:
def Error_Popup_Page(request,message):
context = {'message':message}
return render(request,'InterfaceApp/Error_Notification.html',context)
How it will be used:
def SomeOtherPythonFunction():
try:
#data processing code
except Exception as e:
return Error_Popup_Page(request,'error message')
You're trying to trigger a change on the user browser from on an event that happens on your server. This is impossible to do with Django alone, since Django job is only to respond user requests.
This is where Django is placed in the request chain:
User browser (click on href or ajax event) --> Your server --> Django
--> User browser (gets response and display to the user)
As you can see, there is no way for Django to trigger any event on the user end without the user calling it.
What you're trying to do can be achieved with an async task: in other words, you have to open a websocket and connect the user browser to it with JavaScript.
There are many frameworks for doing this, Celery being the most used in conjuction with Django.
nodejs is also widely used but integrating it with Django is more complex.

Python Social Auth - How to know if social media connect is successful?

I have installed Python Social Auth. I use it to associate user site account with his social media accounts.
Facebook connect link is:
Connect
Redirection works but how to know if social media association is successful?
If an exception is catch, I can display get_messages() function. It's perfect!
But any return if it's successful.
I have tried to custom a pipeline but I have not access to request variable to set message like it: messages.success(request, "Successful message!')
You do have access to request in your custom pipeline:
The pipeline functions will get quite a lot of arguments, ranging from the backend in use, different model instances, server requests and provider responses.
You can read more about it here.
and you can get access to request object like this:
def custom_pipeline(strategy, *args, *kwargs):
request = strategy.request
and do whatever you wanted with messages.
There is an option
SOCIAL_AUTH_LOGIN_ERROR_URL = '/error/'
in python social auth settings which redirects to the url you mention in above setting.
This way you will know whether the connect is success or not.
Hope this is helpful.

Create Django token-based Authentication [duplicate]

I am trying to figure out the best way to implement token based authentication in my django app. An external, non-django application is setting a cookie, with a token, and I have a webservice that can retrieve user information based off of that token. If the user has the cookie set, they should not need to authenticate on my site and should be automatically logged in based on the info passed back by the web service. As I see it, there are a few different options to perform the actual check and I'm not sure which is best:
Write a custom decorator like the one in this snippet and use it instead of
login_required.
Call a custom authenticate method inside base_site through an ajax call. On every page, a check would be made and if the cookie exists and is valid, then the user would be automatically logged in.
Add some javascript to the LOGIN_REDIRECT_URL page that will check/validate the cookie in an ajax call, and automatically redirect back to the referrer if the cookie authenticated.
Is there an option I am missing? Ideally, there would be a way to build this into login_required, without having to write a custom decorator.
Before searching for code, be sure you read the documentation. http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources
Also read the supplied Django source.
You want to create three things.
Middleware to capture the token. This is where most of the work happens. It checks for the token, authenticates it (by confirming it with the identity manager) and then logs in the user.
Authentication backend to find Users. This is a stub. All it does is create users as needed. Your identity manager has the details. You're just caching the current version of the user on Django's local DB.
Here's the middleware (edited).
from django.contrib.auth import authenticate, login
class CookieMiddleware( object ):
"""Authentication Middleware for OpenAM using a cookie with a token.
Backend will get user.
"""
def process_request(self, request):
if not hasattr(request, 'user'):
raise ImproperlyConfigured()
if "thecookiename" not in request.COOKIES:
return
token= request.COOKIES["thecookiename"]
# REST request to OpenAM server for user attributes.
token, attribute, role = identity_manager.get_attributes( token )
user = authenticate(remote_user=attribute['uid'][0])
request.user = user
login(request, user)
The identity_manager.get_attributes is a separate class we wrote to validate the token and get details on the user from the IM source. This, of course, has to be mocked for testing purposes.
Here's a backend (edited)
class Backend( RemoteUserBackend ):
def authenticate(**credentials):
"""We could authenticate the token by checking with OpenAM
Server. We don't do that here, instead we trust the middleware to do it.
"""
try:
user= User.objects.get(username=credentials['remote_user'])
except User.DoesNotExist:
user= User.objects.create(username=credentials['remote_user'] )
# Here is a good place to map roles to Django Group instances or other features.
return user
This does not materially change the decorators for authentication or authorization.
To make sure of this, we actually refresh the User and Group information from our
identity manager.
Note that the middleware runs for every single request. Sometimes, it's okay to pass the token to the backed authenticate method. If the token exists in the local user DB, the request can proceed without contacting the identity manager.
We, however, have complex rules and timeouts in the identity manager, so we have to examine every token to be sure it's valid. Once the middleware is sure the token is valid, we can then allow the backend to do any additional processing.
This isn't our live code (it's a little too complex to make a good example.)

Categories

Resources