python flask rest api auth option storing in mongoDB 3.0 running on docker
I have been looking on a way to auth rest api endpoints that needs to have auth. I will be using Python with flask, flask-restful, yaml, pymongo and passlib. passlib will be used to salt the password that will be stored in mondoDB. A note here is that i will be using mongoDB 3.0 which means that you have to install the un released pymongo 3.0. here is the packets and links you need.
i am installing MongoDB 3.0 using docker. And starting the db. i should end up with one running mondoDB 3.0 named mongo
. i can check that with docker ps
Starting with the mongo module to add a user to a collection in mongo. The createOrUpdateUser
function creates a checks if the user exists in mongo. If that is the case it will update it and add a new time to the updates so i have stored the created date and last update with a timestamp. If the user is not in the db collection one will be created. This function will return the ObjectId of the user that later will be used to get the user.
Next is the getUser
from mongo using the ObjectId. it will return the full json document stored in mongo.
To create the use and salt the password i am using passlib
i’m giving a username, a password, and the mongo host, I’m then using the createOrUpdateUser
to add the user in to a collection called endpoints. the function returns a dict that contains the ObjectId if the new of updated user.
To validate that the password is current I’m using getUser
to get the salted password from mongo in the collection endpoints where i stored that user data. the function is then using a validation option of the salt function that takes the salted password and the password to check if it’s correct. if the verification passes a boolean True is returned else you get a False.
Lest look on the REST api. I am using the flask and flask restful packets to create the REST api. The protected
class init have two keys oid
and key
that should be in the http payload. in the get function i am using “self.reqparse.parse_args(strict=True)” that means that the oid and key key/value have to be in the get payload or the request will be rejected. i am then checking that the key for the oid is valid using validateCheck
if it’s valid you get the {“key”: “valid”} else you get http 401. i am then adding that class to the “api.add_resource(protected, ‘/api/protected’)” which adds a REST endpoint /api/protected
valid
Looking on a test for this to checks that a user is valid if the correct key/oid is passed and then if the wrong key/right oid is passed it can look like this. The assumption here is that the REST api is started and running on localhost and that the docker mongo:3.0 is running on 192.168.59.103. In the setUpClass
i am declaring all variables to self that will be used in test. i am running the tests with nosetests. The first test testAccessValidKey
passed the correct key/oid and should get back http 200. the second test should fail the validation, it passes a invalid key and a valid oid, the api should return http 401.
the source for all the code can be found on my github here Link