I am trying to implement a way for users to stay logged in my website using the JWT DRF implementation.
From the documentation it's suggested that as soon as a token is expired there is no way to refresh them.
Given that a user might close their browser, my only two options are either having long-lived tokens or storing the username/password in localStorage, and both options seem insecure.
Is there a different way to achieve this? Alternatively is there a way to only have long-lived tokens depending on what a user wants (i.e chooses the remember me option)
Yup, JWTs are intended to authenticate sessions short-term only, even with refresh. If you're designing for the browser, I suggest you use regular old SessionAuthentication to keep users logged in longer-term (e.g. 30 days).
If you want to avoid cookies, you can use a combination of a short-lived and long-lived tokens using, for example, OAuth2 -- check out Django OAuth Toolkit which integrates with DRF. The short-lived token authenticates the session just like a JWT, while the long-lived token (30-60 day lifetime) is used to get a short-lived token from your API and can be stored in localStorage.
Related
I'm going to use FastAPI Users for my application. I saw that it generates JWT tokens to perform verification processes in the application. For example, in order to verify user email address or to request password change. Is it a good idea in terms of security?
JWT is state-less authentication and is so useful if you use backend with multiple frontends (mobile app, website UI and ...)
Its security is also Depends on your implementation.
If you use different secret key than default fast-api tutorial (I saw it on some projects!) and use rational expiration date, its secure enough to handle big projects.
consider you should logout every login sessions of specific user, which is logged-out from one client if you have multiple clients. which means you should implement some kind of black-list JWT.
About verifications, I recommend using two factor verification. I usually use security code send to email or SMS code. It's more secure if you consider this scenario:
A user is logged-in on a device and JWT token is not expired. another user using same device in office and can change password without any second factor security layer. If you have code send to the mobile, its more secure and no one can access it easily!
I'm going to build an API in Flask for a (to be created) app which will be built using PhoneGap. In the API many calls will need authentication.
To get into the topic I was reading this tutorial on creating authentication for a Flask-built API. In this tutorial they first show how a user can use basic password authentication for every call, after which token based authentication is introduced.
As far as I understand, the client who calls the API should simply get a token and authenticate every subsequent call with that. In the meantime, the client should keep track of time and either get a new token every 9 minutes (before the old token expires) or simply keep on calling with the token until the client gets an Unauhorized Access message. Am I understanding this correctly?
Moving on, I wonder how it works with Apps on which you login on your phone and then are always logged in whenever you open the app (like for example the Facebook app). This is obviously more convenient to the user than always needing to provide the username/password and I would like to implement something like that as well. I wonder though; how is a permanent logged in feature like this implemented on the server side? Is it done by providing the password and username for every call, or using a never expiring token, or yet a different way?
All tips are welcome!
I've done what you want to do with:
Flask-security https://pythonhosted.org/Flask-Security/:
To manage users and permissions.
Flask-oauth-lib https://flask-oauthlib.readthedocs.org/en/latest/:
Provide oauth functionnality.
So, you have to take a look at Oauth flow, implements a user backend (like Flask-security) and implements an oauth server (with flask oauth lib for example) and bind it to your user backend.
After that, it's oauth standard flow. You just have to give the right token on each api calls and TADA !
With this way you can also, if you want, give access to your api to third-party app thanks to oAuth :)
I'm designing a web application and now I'm working on the authentication function. I read that there are two approaches: cookies and tokens. I do not really understanding how these two work.
I'm planing to use django-rest-framework-jwt if I chose tokens. Here's where I am at :
Tokens
The user sends his data (login and password). The application verifies that the data are correct and calculates a token and then send it back to the user. When the user make a request he includes the token in the request. The application decodes the request and we get the information about the user.
My question :
- How do we get the token? Is it like calculating a hash code?
- How do we get the user information after we decode the token?
- How is it determined that the token is dead?
- Can a web application that uses tokens be used through a browser
Cookies
Same as tokens but cookie are sent using the HTTP header not in request body. Cookies must stored in the server side.
My question :
- In articles I read they say that tokens have the advantage that they have life time. But cookies have that too. So what's the difference between the life time of a cookie and a token?
- How we identify the user who made the request? Do we store a dictionary (cookie, user id)?
I believe "Tokens" as you call it are identical to "Sessions" as on https://docs.djangoproject.com/en/dev/topics/http/sessions/.
Similar to what you stated, Sessions calculate a hash code/id to be sent back to the user to be identified as an authenticated user etc.
To answer your questions directly:
Sessions and Cookies work together. Once Django generates a SessionId it is stored on user's computer through the use of a cookie while it is also recorded in django backend. Therefore, I am not sure if your question is valid. Try reading up at http://www.tangowithdjango.com/book/chapters/cookie.html.
The link above also answers this questions for you. To summarize, the SessionId sent back to the user includes an ID to identify that user as authenticated or any other property etc.
Basically the difference between Cookie-based authentication (by storing sessionIds in cookies on the client) and token authentication is that an authentication token is sent in the http-header 'authentication' field. This is more flexible, since there are REST clients (native clients on phones etc.) that don't support the concept of a cookie at all.
Session Authentication is built-in in Django, session authentication is provided by Django-rest-framework.
Django-rest-framework has a built-in method of passing the token to the client, but you're welcome to implement your own devices.
Tokens are valid until they are deleted from the database. Again, you can roll your own auto-invalidation solution here.
The django-rest-framework documentation is pretty detailed about the different authentication mechanisms it supports. See http://www.django-rest-framework.org/api-guide/authentication
What are the pros and cons of using open id vs auth? Shoud I do both?
That depends whether you want to support Open ID. As to the reasons behind Open ID, in my view the most compelling one is that it avoids requiring your users to have an account just for your site, with all the hassle that involves (yet another username and password to remember).
If you decide you want to use Open ID, there's not need to choose between that and auth - use django-openid-auth, which adds Open ID support to the auth framework.
Definitely try and avoid using an Open ID implementation that doesn't plug into Django's auth framework - you'll lose a lot of the baked-in goodness of Django (model-level permissions etc).
OpenID and OAuth do different things. OpenID lets users log into your site. OAuth lets people give your site access to their data elsewhere. On the other side of the coin, OAuth gives you a secure way to let users access their data in your service from elsewhere.
If you implement OpenID, don't implement an OpenID producer. Everyone's already got an OpenID, whether they know it or not. Just consume openids from elsewhere. Migrating OpenIDs shouldn't be hard. Just make sure that a user account can connect via multiple OIDs, then they can add new ones as needed, and remove when they're done with them.
Edit: Just saw that you were talking about django auth, not oauth. Oops. The second paragraph still stands.
I don't know if any of this is the correct way to do this. But here it goes.
(Please let me know if any of this is totally wrong)
I want to store a JWT against a user in flask, is it correct for me to store this in the database?
Currently I'm attempting to check on each request if they have a valid token but am getting a new token each time.
I'm using this.
app.before_request(check_token)
def check_token(*args, **kwargs):
if current_user:
if current_user.is_authenticated:
if not hasattr(current_user, "token"):
set_token()
elif current_user.token_time + timedelta(seconds=current_app.config["TOKEN_SECONDS"]) < datetime.utcnow():
set_token()
Obviously I've found it doesn't preserve the current_user so the token changes every time I make a new request.
1) Is it good practise to save this token in the database? I'm giving it 300 seconds currently. Or is there another way to save it against the current user?
2) I'm using Flask to render the page and I store the users token like this
<button data-token="asdkjhakjsdnkcz8323lkn42lk3n4kj2nkjn2kj3b4kjnlkj32">
Which I then pass to javascript Xhttp requests to update post comments on the fly. Seems like I probably shouldn't but with such a short validity period seems ok?
The decision whether to store the JWT token depends ultimately on the required security strategy.
The JWT token as well as the refresh tokens indeed store in themselves the sign time and their expiration, but this is not relevant on whether to use a persistent storage regarding their sessions.
From the Flask-JWT documentation:
In production, you will want to use some form of persistent storage (database, redis, etc) to store your JWTs. It would be bad if your application forgot that a JWT was revoked if it was restarted. We can provide some general recommendations on what type of storage engine to use, but ultimately the choice will depend on your specific application and tech stack.
Having said that, if the nature of your information is not so sensitive that a possible leak of the tokens matters, then you can avoid the hassle of persistent storage altogether. Otherwise, on logout you would want to revoke the token by closing the stored session.