Package: djforge_redis_multitokens
Compatible with: Python: 2.7, 3.4, 3.5, 3.6  Django: 1.10, 1.11  DRF: 3.6What Does djforge-redis-multitokens Do?The djforge-redis-multitokens is a plugin for Django Rest Framework that allows you to create multiple tokens for each
user(one per device or browser) and store them in Redis. Here’s why you may want to use this plugin:Your users have multiple devices and a log out from one device(or browser) should not log the user out on other devices(or browsers)Token retrieval, validation, and updates should be fast. This plugin uses Redis, can’t touch this!Security is important to you. This plugin encrypts users’ tokens so even if an attacker gets access to all your tokens they would not be able to do anything with them.Note: device in this document means a physical one or a browser.How to InstallFirst, download the package and install it using pip:pipinstallgit+https://github.com/ToReforge/djforge-redis-multitokensOr simple:pipinstalldjforge-redis-multitokensThen, you’ll need Django, Django REST Framework, and Redis. Finally, your Django app needs to be able to talk to Redis, so you’ll need a library likedjango-redisordjango-redis-cache. Follow the instructions here(http://django-redis-cache.readthedocs.io/en/latest/intro_quick_start.html) to setup Django with Redis.How to Use ItCreate a Redis DB For TokensOnce you’re done with the installation step, make a Redis db for your tokens in your Django settings file:CACHES={# other Redis db definitions above# tokens db definition'tokens':{'BACKEND':'redis_cache.RedisCache','LOCATION':'localhost:6379','OPTIONS':{'DB':2,},'TIMEOUT':None,}}Note:In the above definition, we’re setting “tokens” as the name for the Redis db that will contain tokens. You can change this name, more on that later.TIMEOUTis used to expire tokens.TIMEOUT: 10000means that new tokens will be valid for 10000 before they expire and are removed from Redis.Custom SettingsDJFORGE_REDIS_MULTITOKENS={'REDIS_DB_NAME':'custom_redis_db_name_for_tokens','RESET_TOKEN_TTL_ON_USER_LOG_IN':True,'OVERWRITE_NONE_TTL':True,}Put the above in your Django settings module to customize the behavior ofdjforge-redis-multitokens:REDIS_DB_NAME: set this to the same name you defined for your Redis db(“tokens” in the above defnition).RESET_TOKEN_TTL_ON_USER_LOG_INextends the life of tokens byTIMEOUTseconds(set insettings.CACHES).OVERWRITE_NONE_TTLwill overwrite the previous ttl ofNone(Nonemeans Redis will never expire your token) set on a token. Set this toFalseif you don’t want your immortal tokens to become mortal.In other words, if you setOVERWRITE_NONE_TTLtoFalse, the ttl of tokens with ttlNonewill not change. They will never expire.Setup Token AuthenticationThere’s complicated logic involved in token authentication, butDjango REST framework(DRF)comes with a “pluggable” authentication module that supports token authentication so thatdjforge-redis-multitokenscan change where tokens are stored.
We want our tokens to be stored in Redis, so we have to change the default authentication class:REST_FRAMEWORK={'DEFAULT_AUTHENTICATION_CLASSES':(' djforge_redis_multitokens.tokens_auth.CachedTokenAuthentication',),# your other DRF configurations goes below}Note:With this setting, we ask DFR to useCachedTokenAuthenticationto check if users have the right token whenever they log in.CachedTokenAuthenticationis a subclass of DRF’sTokenAuthenticationwhich overrides how tokens are fetched from storage.Create New TokensUsually, you want to create a new token whenever a user logs in from a new device:fromdjforge_redis_multitokens.tokens_authimportMultiToken# create new token in your login logicdeflogin_handler(request):token,_=MultiToken.create_token(request.user)# request object in DRF has a user attribute# _ variable is a boolean that denotes whether this is the first token created for this userNote:Before your login handler function is invoked, DRF checks to see if your user has a valid token. So, the above function is not invoked for users who have a valid token.MultiToken.create_tokentakes an instance ofsettings.AUTH_USER_MODELwhich Django calls theUsermodel.The_variable, if it isFalse, tells you that the user is logged in on another device(or browser).Thetokenobject has two attributes:keyanduser. DRF expects custom tokens to have these attributes.keyis the string user receives as their token anduseris an instance of thesettings.AUTH_USER_MODELmodel.Expiring TokensWhen a user logs out(usually by pressing the “log out” button on your user interface), you usually expire the token associated with that device:fromdjforge_redis_multitokens.tokens_authimportMultiTokendeflogout_handler(request):# DFR request object has an `auth` attribute which is of type MultiTokenMultiToken.expire_token(request.auth)Sometimes, you want to expire all tokens of a user. For example, user changes his/her password and you want to force log out the user on all devices:fromdjforge_redis_multitokens.tokens_authimportMultiToken# after user changes passworddefpassword_changed_handler(user):MultiToken.expire_all_tokens(user)Get User From TokenWhen you have access to user’s token, you can get theuserassociated with that token:MultiToken.get_user_from_token(key)Note:Thenkeyhere is astrobject, so theget_user_from_tokenmethod expects the key as a string.MultiToken.get_user_from_tokenreturns aUserwhich is defined bysettings.AUTH_USER_MODEL.Immortal TokensIf you want your tokens to never expire, you need to do 2 things:SetTIMEOUTtoNoneinCACHES:CACHES={# other Redis db definitions above# tokens db definition'tokens':{'BACKEND':'redis_cache.RedisCache','LOCATION':'localhost:6379','OPTIONS':{'DB':2,},'TIMEOUT':None,}}SetOVERWRITE_NONE_TTLtoFalseinDJFORGE_REDIS_MULTITOKENS:DJFORGE_REDIS_MULTITOKENS={'REDIS_DB_NAME':'custom_redis_db_name_for_tokens','RESET_TOKEN_TTL_ON_USER_LOG_IN':True,'OVERWRITE_NONE_TTL':False,}How to DevelopClone the repo, go to the root directory(wheresetup.pyis)pip install--editable.cd test_app/pip install-rrequirementscd demopython manage.py migratepython manage.py test