Package: dj-api-auth
dj-api-authis a Django application, providing an AWS-alike API auth solution.When I was seeking a simple solution rather than intricate OAuth, I was inspired by this articleDesigning a Secure REST (Web) API without OAuth.
Thanks to the author and the comments.FeaturesAPI key, SEC key related formsEach API key can be associated with a set of APIAPI can be associated with user,  your legacy code withrequest.userunderneath can work smoothly withdj-api-authAdd auth by simply put a decorator on your view.Discover API with auth enabled automatically, these auth-required APIs will display in assignable list when creating API keysA Django command to scan and update API information to database.How it worksGenerate a pair of API key and SEC key, assign some APIs to it.Client put API key and current UNIX time asapikeyandtimestempin requestURLClient also generate asignatureby calculate a SHA256 value on the whole URL(withoutsignature) by its known SEC key.Server side will verifyistimestampfrom client in reasonable drift compare to server time.isapikeyfrom client existsis the API client trying to access allowed for theapikeycompare thesignaturewith the one calculated on server side by same algorithmif any verification failed, return 403 error with brief messageAdd to your projectAdddjapiauthtoINSTALLED_APPSinsttings.pyThere are two optional settingsAPI_AUTH_ALLOWED_TIME_DRIFToptional, set the allowed time drift between server time and thetimestampparameter in coming URL.format: integer, unit: seconddefault: 300, (5 minutes)API_AUTH_ADMIN_USER_FILTERoptional, when creating API keys, you can assign the API key to an user, this filter is used to filter the users showing in the API key creating form.format: dictionary, the filter parameter will be passed toget_user_model().objects.filter(). e.g.{'name_startswith': 'admin'}default: {}, means all users will show in the API key creating form.Generate/Manage API and SEC keyIf you haveadminenabled for your project, you can find these features inadminsite. Otherwise, you can import forms fromdjapiauth.formsor write your own form based on models indjapiauth.modelsAdd auth for function-based viewsFor legacy views, we provide utility functionurl_with_authindjapiauth# add auth for a browser-oriented viewurl_with_auth(r'^hello/$','djapp.views.index'),#...For API views, simply add@api_authfor the view afterfrom djapiauth import api_auth@api_authdefapi_whoami(request):returnJsonResponse({"user":"feifan","boss":"lidan zhou"})Add auth for class-based viewsFor class-baesd views, simply adddjapiauth.utility.AuthMixinas a base class to get auth protection.fromdjapiauthimportAuthMixinclassProtectedView(AuthMixin,View):defget(self,request):returnHttpResponse('hello, auth')classUnprotectedView(AuthMixin,View):api_auth=Falsedefget(self,request):returnHttpResponse('hello, no auth needed')and add URL mapping inurls.py...url(r'^classbased1/$',apis.ProtectedView.as_view())...Scan APIThere’s a Django commandreloadentrypointsto help you to collect and save all auth-required APIs to database.API Key and associate API setsince version0.8, I start using a tree-alike structure to speed up matching incoming URLs.when you upgrade from previous versions, you should run following commands to expand database fields and build matching tree for each API key.python manage.py migrate
python manage.py repairapikeysError messagesparameter missing, any ofapikey,timestamporsignaturemissing in URLtime drift xxx, check your local time and server time. You can implement an API to return server timeentry point not allowed for the API key, check the assigned API for this API key inadminsite or anywhere else you manage API keyssignature error, obviously, signature mismatchDEMOSource code underexample/djappfolder.Test code is underexample/test/, we havepythonandjavascripttest code ready.Server application provides 2 APIs/hello/: reused the code of index view, add an auth layer on it/goodbye/: a view you must access it by the signature stuffDIY:Start the djappthere’s already one pair of API+SEC keys:483a570a,d7228d70cd7f456d9bfdc35ed8fee375modify variableURLintest.py, orURLintest.jsGenerate API key and SEC key from localhost:8000/admin/xxx, modify variableAPI_KEYandSEC_KEYintest.pyortest.jsRunpython test.pyornode test.jslogin admin site with admin user:admin/123, remove all APIs associated with483a570a, try to run the test code again, you should see 403 errors__main__.APIException: (403,'{"error":"entry point not allowed for the APIkey"}')modify the API key to an invalid onemodify the SEC key to an invalid onemodify your local time to one hour agoThanksThanks for the Javascript test code from Neil Chen (neil.chen.nj@gmail.com)