This is more of a general newbie question:
How do desktop applications that hook up to a service typically verify users? How would I do this for a Django app? Would it be as simple as passing the credentials to a blank view that checks the username / password?
How is it typically passed?
Thanks
You can create a custom login view on the django side, as detailed here. Have it return a message based on the whether the username and password parameters (should probably be sent via a HTTP POST, preferably over SSL) were valid. On the desktop client, if the response is valid, it should get the value of the cookie that got sent along with the response, and it should keep that cookie with every HTTP request that is made for the rest of the session.
Not sure what you meant, but for example if you want to check user's credentials from desktop python application by some method in django app, you can use httplib module and send POST request and then check the response you get. Make something kind of:
>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
>>> print f.read()
(Example taken from Python docs)
Related
I was trying to put
session['logged_in'] = True
in the session, but in another blueprint it doesn't persist... Why is that?
Is there any better way to keep something in the session?
Extended:
I have a blueprint giving a form to login. When done and submitted, it will set a session key like above. Then it redirects via
return redirect(url_for('admin.index'))
to admin page where If I call the key via
session.get('logged_in')
I get "None" Instead of the True or False one.
I think I understand your confusion now~
Your flask session won't store anything on the server.
the 'session' dict is filled by the cookies from the client request.
Again. that is:
client make login request to server, and got a [login success] response as well as a [cookies] which contains the !!!sessionINFO!!! you think are stored on the server side.
Next time, you must send the whole cookies to the server again, then your session in the server may have data.
Browser will do this for you.
If you use a local client, say python requests library. Then be sure you are making requests with session (for requests-lib, it's requests.Session())
------------------OLD-------------------------------------
Though not an expert, but the case you described should not have happened.
The session is cookies data encrypted with a secret, if you have gone through the document mentioned by Beqa.
Just set
app.secret = '........'
And use session as a dict.
just FYI,
client request---->server (encrypt your_data 'logged_in' and client_relating_data 'maybe: ip, host or etc.', and put the encrypted info in cookies 'session=....') ------> client (get response with cookies)
client request again -----> server (decrypt the cookie 'session=...' with your secret), find the 'logged_in' data and know you are logged in.)
the cookies is something like below.
So, I'm not sure what's actually your trouble when using session, and put some basic information here. Just hope it helps in case.
So I'm working on a django project, and one of the objectives is to allow a separate python script to make a HTTP request (using Requests library) to get json data after being authenticated. This works fine, the problem is that if I directly go the url the request.get object uses, I can see all of the data (without any user authentication being involved). This makes my authentication process pointless, as the data is easily visible by simply going to the url. So how would I hide the data on the web side from being viewed, but still allow a GET request to pull the data to my script?
On a side note, I already have a authentication system for the web interface portion of my project (which displays the data). I've tried putting it behind that but to no success.
import json, requests, _mysql
login_attempt = requests.post('http://127.0.0.1:8000/m_app/data_login/',
{'username': 'test', 'password': 'password1234'})
if login_attempt.content.decode('UTF-8') == 'Successful':
print('Logged in.')
else:
print('Not logged in.')
cookies = dict(sessionid=login_attempt.cookies.get('sessionid'))
data = requests.get('http://127.0.0.1:8000/m_app/load/data', #if I type this URL in, I see the data
cookies=cookies)
print(data.content) #prints desired data
By default all your views in django are public, but it's easy to make them protected by checking request.user or using a login_required decorator.
I am using Flask-Restful to build a REST service. The iOS device will then connect to this REST backend to sync the local data.
The service will be accessed over a https connection.
The REST service is stateless and the user has to authenticate upon each request. Hence the username and password will be sent in clear format to the REST service. The backend will hash the password and check against the existing hashed password in the database.
api.add_resource(Records, '/rest/records/<string:email>/<string:password>/<string:ios_sync_timestamp>')
Now one problem I see with this approach is that the username and password are in clear format as part of the GET url. The server log will obviously track this. Now if my backend was ever hacked into, the log files would compromise all the usernames and passwords.
What is the best solution to this? I was thinking maybe sending username and password as POST arguments, but how do I that with GET requests then?
class Records(Resource):
def get(self, email, password, ios_sync_timestamp):
pass
def post(self, email, password, ios_sync_timestamp):
pass
To authenticate each requests with a username and password like you want, you should use: Basic Authentication.
To use it, it's pretty simple and it works with all HTTP methods (GET, POST, ...). You just need to add an HTTP header into the request:
Authorization: Basic <...>
The <...> part is the username:password encoded in base64.
For example, if your login is foo and your password is bar. The HTTP header should have this line:
`Authorization: Basic Zm9vOmJhcg==`
Through your HTTPS connection, it's secure.
EDIT: Using Flask, you can use Flask HTTP auth to achieve this "automatically".
Another solution instead of the Basic Auth in each call as suggested by Sandro Munda is to generate an API Key using a POST to first check credentials request and then passing it in the request headers. Then you can verify it in each API handler for a strict-grained checking or application-wide using a #before_request handler.
Workflow
Client sends a POST to the server with the credentials (username/pass)
Server replies with an API Key. Like an hexdigest of something secret.
from now on
Each time the client needs to send an API request it adds an header (let's call it X-API-Key with the API Key.
buddies
One of my GAE restful service needs login with admin account. And I'm writing an automation script in python for testing this service. The script simply do a HTTP POST and then check the returned response. The difficult part for me is how to authenticate the test script as an admin user.
I created an admin account for testing purpose. But I'm not sure how to use that account in my test script. Is there a way that my test script can use oath2 or other approach to authenticate itself as a test admin account?
Ok I think this might be what you are looking for, client libraries to authenticate and yeah I believe appengine now recommends using the oauth2 for any kind of authentication:
https://developers.google.com/accounts/docs/OAuth2#libraries
Then you get an auth token where you pass in headers on your restful request like:
# Your authenticated request
Authorization: Bearer TokenHere
Then in your handler you get it like:
try:
user = oauth.get_current_user('https://www.googleapis.com/auth/userinfo')
except NotAllowedError:
user = None
# then from the first link you should be able to access if
user.is_current_user_admin()
This is how I authenticate on android, but I only do this once and store it in session and just enable cookie jar on the httpclient.
Can anyone advice me on a good library or else how to go about having a Python appengine based application using OAuth to authenticate to another server?
I have an application on appengine that expects user input. I would like the user to be able to upload an image, which I would put in imgur.com and would be able to show to the user back on my page. To be able to do that, I need to be able to authenticate to api.imgur.com hence the question.
Have a look to python-oauth2 project.
A Client example:
import oauth2 as oauth
# Create your consumer with the proper key/secret.
consumer = oauth.Consumer(key="your-twitter-consumer-key",
secret="your-twitter-consumer-secret")
# Request token URL for Twitter.
request_token_url = "http://twitter.com/oauth/request_token"
# Create our client.
client = oauth.Client(consumer)
# The OAuth Client request works just like httplib2 for the most part.
resp, content = client.request(request_token_url, "GET")
print resp
print content
I believe the simplegeo oauth2 does not play well with GAE. Mike Knapp's library on GitHub is nice and simple, no install needed.
maybe you can use imgur-api, http://code.google.com/p/imgur-api/wiki/ImageUploading