How to Authenticate to Anchor.fm form using Python? - python

I'm trying to use Python to authenticate to https://anchor.fm/login.
The problem is that the payload requires a _csrf property.
So I don't think it's possible to use a simple POST method.
So, I would like to know if it is possible to get the attributes of the form (id="LoginForm") to do the authentication:
If yes, is there any package that helps me to do this? Or some other method.

The login page makes a GET request to https://anchor.fm/api/csrf to get a csrf token. This request also sets a cookie, which is then sent together with the login form. I haven't checked that, but it seems it should be enough to make that GET request, grab the csrf token and the cookie, and attach them to the POST you make with the login form. (the csrf token in the _csrf body field, as you noted)

Related

How to set authorization header (JWT)

I am working on JWT authorization and I'm not able to figure out how to send the JWT as a request header for every request, so that I can use it to check if the user is authorized.
Right now, I am generating the JWT immediately after login, and setting it as a cookie. I want to use header instead of cookie. How can I achieve this?
I am using django 1.6, if it is relevant information.
It really depends on your request library. Could you tell me what library you're using to make requests? BUT: most request libraries out there should let you set the header of the request to include a JWT. Therefore, when the server receives the request, the server will "know" you are authorized because the JWT is in the header.
Take a look at How to add JWT to authorization header? as an example!
As for this:
Right now, I am generating the JWT immediately after login, and setting it as a cookie. I want to use header instead of cookie. How can I achieve this?
It's totally fine to set your JWT as a cookie. What you must do for every request is to get the JWT from the cookie. Look at: https://www.w3schools.com/js/js_cookies.asp for more details!

Using double submitted CSRF tokens (header + cookie) in HTML forms?

I'm using a combination of flask-jwt-extended for JWT authentication, and I've enabled CSRF protection, meaning for certain HTTP methods (PUT, POST, DELETE...), it is required that the value in the cookie and the HTTP header match.
This works fine for my API requests, where I just construct the HTTP request in JS with the header set correctly, but I want to use Flask-Admin, and allow access based on the JWT tokens. I did this by decorating the is_accessible function in Flask-Admin's ModelView with #jwt_optional and checking within it.
However, now when I try to perform any modifications through Flask-Admin, I get an error message from flask-jwt-extended, stating that I didn't properly include my CSRF tokens. This is true, as I'm using the default forms that come with Flask-Admin.
My question is, what is the best solution? Is it possible to disable CSRF protection only for certain paths? (And enable Flask-Admin's own CSRF protection for them?) Should I modify the views and insert JS that is triggered by the submit button but actually submits an XmlHTTPRequest? Should I implement the JWT authentication for Flask-Admin views in a different way?

How to use authentication token in Django with Django OAuth Toolkit (not REST)

I'm using the following library http://django-oauth-toolkit.readthedocs.io/ which seems to not be as well documented as I would like, and after I followed its tutorial I am able to have a working system in which I have protected views that need the authorization token, and I can access them using curl and adding the token. Curl is nice to test, but it's not practical, and I failed at developing it.
So I have a very simple protected view:
class Test(ProtectedResourceView):
def get(self, request, *args, **kwargs):
return HttpResponse('Hello, OAuth2!')
If I try to access, I will get a 403, and if I ask for the token and put it in the header using curl I can actually get it to work.
In the other hand, I have another view that gets the authorization_token, lifetime, refresh_token, .. in a dictionary (after using JSON from Django).
At this point I'm lost. I don't know what to do with the authorization token so that the user can actually use it and access to the protected view. I tried to manually add the token to the cookies but it didn't work and doesn't seem to be a good idea neither. I guess after I do something, the user can access the protected view.
Thanks.

How is Flask-Login's request_loader related to user_loader?

I apologize in advance for asking a rather cryptic question. However, I did not understand it despite going through a lot of material. It would be great if you could shed some light on this.
What is the purpose of a request_loader in flask-login? How does it interact with the user_loader decorator?
If I am using a token based authentication system (I am planning on sending the token to my angularJS front end, storing the token there and sending that token in the authorization-token header), will I need a request_loader or will a user_loader (where I check the auth header and see if the user exists) suffice?
From the Flask-Login documentation:
Sometimes you want to login users without using cookies, such as using
header values or an api key passed as a query argument. In these cases,
you should use the request_loader callback. This callback should
behave the same as your user_loader callback, except that it accepts
the Flask request instead of a user_id.
So, to answer your question, they both serve the same function for Flask-Login. They are both used to load the user. request_loader, however, is appropriate for custom logins.
Here's a great tutorial I found that utilizes request_loader to take advantage of token based authentication (The post is not my own, I'm merely sharing the link): http://gouthamanbalaraman.com/blog/minimal-flask-login-example.html
I need to make this clear.
This is the reason why you shoud use request_loader with flask_login.
There will be a lot of #login_required from flask_login used in your api to guard the request access.
You need to make a request to pass the check of auth.
And there will be a lot of current_user imported from flask_login,
Your app need to use them to let the request act as the identity of the current_user.
There are two ways to achieve the above with flask_login.
Using user_loader makes the request to be OK for #login_required.
It is often used for UI logins from browser.
It will store session cookies to the browser and use them to auth later.
So you need to login only once and the session will keep for a time.
Using request_loader will also be OK with #login_required.
But it is often used with api_key or basic auth.
For example used by other apps to interact with your flask app.
There will be no session cookies,
so you need to provide the auth info every time you send request.
With both user_loader and request_loader,
now you got 2 ways of auth for the same api,
protected by #login_required,
and with current_user usable,
which is really smart.
To verify users with Flask-Login's session_id for frontend requests through Angular, you must set the withCredentials configuration flag to true.
That is, if you are using Angular's $http.post(url,data [,config]) or $http.get(url [,config]), make sure the config object contains the property withCredentials set to true. This will instruct the browser to use its cookies in the same way it would for a full-on page visit.
For example,
$http.post('/api/login',{username:'myusername',password:'mypassword'},{withCredentials:true})
will post the data {username:'myusername',password:'mypassword'} to your site/app's /api/login route and, if you're using Flask-Login and are logged in, Flask will know.
You can set this behavior for all $http service requests by setting
$httpProvider.defaults.withCredentials=true
somewhere in your app. Currently, I have that line of code in my app.config block, which seems appropriate to me:
var myApp = angular.module('myApp');
myApp.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
});
(Since this post is about Flask, folks may want to send form data through Angular in such a way that it can be found in request.form, which has a similar solution, fyi.)

How do you use rauth with Django?

The python lib mentioned in OAuth website rauth seems to be simple and best one to use. So, I want to use it in Django and unable to actually implement it.
Here is my issue.
# I do something like this initially
from rauth.service import OAuth2Service
from django.shortcuts import render_to_response
def page(request):
service = OAuth2Service(
consumer_key = "..",
consumer_secret = "...",
.. )
url = service.get_authorize_url(redirect_uri="http://mysite.com/redired-url")
# this url is where the user accepts or not.
# which redirects with authorization code.
return HttpResponseRedirect(url)
Now, when user opens page, it directly redirects and asks user to allow or reject.. If user allows, we get authorization code at redirect-url
To get access token from authorization token,
rauth lib mentions to do so which I have to put under a different view corresponding to redirect-url
data = dict(code='foobar',
grant_type='authorization_code',
redirect_uri='http://example.com/')
token = service.get_access_token('POST', data=data)
The problem is with service object. I created service instance in one view, i need to use it in another view to get access token..
Where I am going wrong..? How to get it done.
Okay there's various ways to handle this in the context of a web app. I would highly recommend taking a look at the Facebook Flask example in the examples dir.
The basic idea is provide an authorization view and a redirect view. You want to have the provider redirect to the redirect view and therein you should do all the stuff you'd expect to be able to do assuming you've been authorized by the user. Otherwise, you should bail out and possibly inform the user as to why.
Now what I typically do is keep the service wrappers in a separate module, not in a view, and then import them into the context I need them. You can do things to initialize them dynamically and such. But reference the link I posted for a simple implementation. I think this should do what you want. I realize it's not Django, but the idioms are pretty close with the simple case of views like this.
Update - Upon further review, I saw a need for clarification. You won't get the access_token until AFTER the user clicks "Yes" on the reddit authentication page. It will then redirect, with a code and state information in the query, to the URI you provided at the beginning of your process.
To receive the OAuth2 tokens posted back in the redirect_uri's view, you will need to get the URL parameters from within the view class/method:
code = request.GET.get('code', '')
This will give you a variable containing the code generated from the first request (it's in the URI as a parameter).
Make sure you check your "state" variable as well, retrieving it the same way, otherwise your security goes out the window.
What you do from there depends on if you're using rauth or praw, but you can use the information gleaned above to generate the appropriate request to get said access token.
Basically, your callback view (redirect_uri) handles all reddit verification and processing. Your initial view, for the most part, either a generated link or a redirect to reddit.com.

Categories

Resources