Passing django user as redirect request header - django

I have a (non-django) application A that requires a username to login. This app allows for pre authorization, which I want to provide from my django application B. However app A requires that the username is set as a remote_user request header. What I tried to do is create a view in django app B that redirects to app A passing a remote_user header.
urls.py
url(r'^{0}to_app_a$'.format(DJANGO_BASE), 'app.views.to_app_a')
views.py
def to_app_a(request):
response = redirect('http://app_a')
response['remote_user] = request.user
return response
The problem with that is that the header is lost on redirect and never reaches the request to http://app_a external app. It has been suggested to use cookies instead, but unfortunately app A won't accept anything else than a remote_user request header.
Has anyone come up with a solution to such issue?
Thank you

Related

Djoser password reset implementation

I am using djosers for my authentication on django backend which eventually i'll be connecting to flutter frontend and i am having trouble implementing the password reset functionality...
from what i have understood, first i need to hit the /users/reset_password/ with email body which will eventually give me the token of authentication which will be used further on confirm reset but the first thing i dont understand is PASSWORD_RESET_CONFIRM_URL field in the settings, like it needs a front end link with uid and token placeholders but what is this token field and what is this PASSWORD_RESET_CONFIRM_URL but i managed to look over a stack overflow question and filled it but now when i hit /users/reset_password/ i get this error:
[WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions
settings:
DJOSER = {
'PASSWORD_RESET_CONFIRM_URL':'reset/password/reset/confirm/{uid}/{token}',
'LOGIN_FIELD' : 'email',
'USER_CREATE_PASSWORD_RETYPE' : True,
'SERIALIZERS': {
'user_create': 'auth_app.serializers.UseriCreateSerializer',
'user': 'auth_app.serializers.UserCreateSerializer',
}
}
urls.py:
urlpatterns = [
path('',home,name='home'),
path('addInForum/',addInForum,name='addInForum'),
path('addInDiscussion/',addInDiscussion,name='addInDiscussion'),
path('<str:forum_id>/getDiscussion/',getDiscussion,name='getDiscussion'),
path('getDate/',getDate,name='getDate'),
path('reset/password/reset/confirm/<str:uid>/<str:token>/',PasswordResetView,name='PasswordResetView'),
# url(r'^reset/password/reset/confirm/(?P<uid>[\w-]+)/(?P<token>[\w-]+)/$', PasswordResetView.as_view(),),
]
views.py
#api_view(['GET'])
def PasswordResetView(request,uid,token):
post_data = {'uid': uid, 'token': token}
return Response(post_data)
Please remember that djoser should be part of your REST API based on Django REST Framework. You also need to think differently about the url routing in regard of your frontend app..
Usually urls in the form mydomain.com/some_url/whatever are considered "frontend urls" and parsed by routing of your frontend app. On the other hand urls in the form mydomain.com/api/something are considered API urls that are routed via Django's urls.py. I will refer to them as Fronted_URL and API_URL respectively.
So: resetting password works like this. The user that forgot their password and wants to reset it, surely needs to fill some king of form. This form needs to be sent to APIURL returned by resolve('user-reset-password') (by default this returns something like /users/reset_password/)
Here comes PASSWORD_RESET_CONFIRM_URL setting. Because after the body is accepted by the APIURL mentioned above, a mail will be sent to the user with a link that will point to URL entered in that setting. And it has to be FrontendURL! It should be routed by your frontend APP and preferably display some screen. But in the background your frontend app should send the values of uid and token fields to APIURL returned by resolve("user-reset-password-confirm").
This flow allows your frontend app to properly handle the response and display appropriate message to the user and then maybe redirect them to some other screen.
If you don't have a routed frontend app (probably written using REACT, ANGULAR or VUE) then you probably don't need a REST API and should just stick to django-allauth.

Redirect From REST_API Response

I am using Angular and Django in my stack for a website, and after a user registers it emails them a link to activate their account. As of right now everything is working but the link takes the user to the Django rest framework page.
I've been returning responses in my app like this
data = {'success': True, 'message': 'An account has been activated.', 'response': {}}
return Response(data, status=status.HTTP_201_CREATED)
I am curious on how to redirect a user back to the login page which at the current moment would be a localhost page such as http://localhost:4200/#/authentication/login.
From research I have found methods like
return redirect('http://localhost:4200/#/authentication/login')
but I am wanting to keep my responses consistent. Is there a way to redirect a user while still using the rest api Response object?
After thinking about the comment posted by Muhammad Hassan, I realized I was thinking about this all wrong. Instead of sending a Django url I have change the email to send a URL to an Angular page I made and then I just sent an HTTP request from that page to the Django URL.

How to GET request if login_required in DJango

Here my API:
#login_required
#api_view(['GET'])
def get_order(request):
order_list = Order.objects.values("user_name",
"user_surname",
"order_date").all()
return HttpResponse(json.dumps([x for x in order_list])
The problem is when i add #login_required, i'm trying to do a Postman GET request using BASIC authentication with username and password.
If i remove the #login_required, i can perform a succesful GET request without auth in Postman.
First, login with your browser. Next, locate where the corresponding authentication cookie is stored in your browser. Copy it to your clipboard. Finally, paste the cookie and pass it along with the GET request in Postman:
The name of the cookie is sessionid.

Python Social auth authentication via access-token fails

I am currently developing a serverbackand with Django (1.7) that should handle authentication via social Networks by using python-social-auth.
I followed the Tutorial on this site, which describes the process for a simple Webapp.
This worked perfectly for Google and Twitter login.
Since the Server should be just a REST-FULL Backend I decided to get the Access-Token on the client side and send it to the server.
The server than will authenticate with it. This process should be no problem and is even given as an example in the docs of python-social-auth.
However if I do set everything up I will receive an error that says: "Backend not Found 404".
Here a minimal part of the project:
settings.py: (I also included API_KEY and SECRET)
AUTHENTICATION_BACKENDS = (
#'social.backends.facebook.FacebookOAuth2',
'social.backends.google.GoogleOAuth2',
'social.backends.twitter.TwitterOAuth',
'django.contrib.auth.backends.ModelBackend',
)
views.py (for the authentication view)
from django.contrib.auth import login
from social.apps.django_app.utils import psa
#psa('social:complete')
def register_by_access_token(request, backend):
token = request.GET.get('access_token')
user = request.backend.do_auth(request.GET.get('access_token'))
if user:
login(request, user)
return 'OK'
else:
return 'ERROR'
This i copied strait from the docs and only changed backend.do_auth to request.backend.do_auth. This seems to be an error in the docs.
urls.py:
...
url(r'^register-by-token/(?P<backend>[^/]+)/$', 'register_by_access_token')
...
Also as suggested in the docs.
I just tried to get this working just for google-oauth because there is a simple js-lib that gives you the access-token.
This also worked quite nice and I send a request to
GET http://localhost:8000/register-by-token/google-oauth2/<access-token>/
As described above the return was a 404 Backend not found.
I did a little bit of debugging and found out that the error is raised in the login function not the do_auth() function of the backend.
Therefor the actual authentication process works. I also tried using a random generated string as a token and got an according error, that the user cannot be authenticated.
The funny thing is that the user even has a property backend which holds 'social.backends.google.GoogleOAuth2' as it should.
Thank you if you stayed with me for the long post, and I hope someone has an idea what could be wrong :).
Looking forward to your answers.
In you register_by_access_token view, you are getting access_token in GET params
user = request.backend.do_auth(request.GET.get('access_token'))
and url you defiend is:
url(r'^register-by-token/(?P<backend>[^/]+)/$', 'register_by_access_token')
So you need to request something like:
GET http://localhost:8000/register-by-token/google-oauth2/?access_token=<access_token>
whereas, you are doing:
GET http://localhost:8000/register-by-token/google-oauth2/<access-token>/
You are passing access_token in url params, which is wrong.

Django API for login/logout with S3 site is not creating cookies

I'm working with a static webpage hosted on S3 and I'm using a Django as my api for session management.
I have my JS code on S3 POSTing to django when users sign in to my web site but I'm not getting any cookies saved on my browser.
I'm not sure if it's the jQuery $.post that is not accepting cookies or if it's Django that's not allowing the sending of cookies. How would I overcome this?
I currently also have a url endpoint on my django app where I can check if cookies are working but when I hit the url I get the standard message
Please enable cookies and try again.
Although my browser accepts cookies.
I get these urls to work fine when I use a Django rendered page to interact with them.
Any help would be greatly appreciated - thanks
Edit - showing code:
I use Janrain to allow user to login via facebook, twitter, etc..
how Janrain works
user clicks sign in button, uses facebook/wtv to login
Janrain get's user data on their servers and gives you a token which I post to django via this function
janrain.events.onProviderLoginToken.addHandler(function(tokenResponse) {
$.ajax({
type: "POST",
url: post_form_url,
data: formdata + "&token=" + tokenResponse.token,
success: function(res, textStatus, jqXHR) {
//do stuff now that we are logged in ...
console.log(jqXHR.getResponseHeader('Set-Cookie')); //returns null
//$('#redirect').submit();
},
});
In Django
def login_via_janrain(request):
if request.method == "POST":
janrain_token = request.POST.get('token')
// communicate w/janrain api to get info from this token (i.e. who just logged in via this token)
#create (or pull) user based on data returned from janrain api and do a Django login
auth.login(request, user)
#return success msg to $.post (session cookies should be automatically included in the response)
return HttpResponse("success")
Using S3
I currently have a static site hosted on S3. I tested these urls using django rendered views but ultimately I want the S3 site to render the views and just use django as an api endpoint.
I can currently login from the S3 site but after a successful login I have no cookies to show for it... I think django isn't sending back cookies...