I am working on creating an application , where i am authenticating the user using a third party oauth provider.
i am getting access token and token secret from the provider.
Now i need those access tokenans token secret with every api call. so where should i store that in my express app. Should i store in session or should i do something else .
I am currently storing in session but read it is volunerable to csrf.
Trying to know what is the best way to do it.
These tokens should be stored in the Users table/collection in the database. That way you can easily fetch them from the Users database table before every API call.
There are several ways to do this, all depends of what you're able to do.
The Secret
Store the secret on a DB, (Redis, Mongo, SQL, etc).
Here you will be sure that's more secure, also you will be able to consume from any of your server, not just the one who generate it.
The token
You can pass it as a header to your FE, and then stored on a cookie, local storage or session storage, then pass it to your BE with each petition, take it and use it to call to your Provider.
This is my approach, maybe is not the only one, but for me is the most secure.
Hope this helps you!
Related
I use jwt tokens in my project. Long-lived refresh tokens to authenticate and short-lived access tokens for protected resources. The refresh token is saved in a http-only cookie to reduce the risk of xss attacks. The access tokens will be only stored in my vuex store of my frontend. Should I renew my refresh token if the user changes the password? I don't store refresh tokens in my database, because as I understood the the main purpose of jwts is that I can use cryptography to verify my incoming refresh token and do not have to look it up in my database (then I don't have to use jwts at all).
But how do I invalide an already sent refresh token e.g. on an other device or browser? If I don't use a database to store refresh tokens the token would be valid as long as the expiration time is. I appreciate any advice.
Since you don't store tokens in the database you can't invalidate them remotely. But there are some common practices to overcome this issue.
NOTE: These are not standards, Just a practice used by major
companies.
1. Store tokens in Cache Database (Not in the main DB)
Storing JWT tokens in the cache database such as Redis or Memcached will allow you to retrieve and verify the token much faster. To invalidate the token you just need to remove it from the cache.
2. Use short-lived access and refresh token
This is mentioned in a lot of Security Submits. Expert says to set a very short life (in minutes) to both access and refresh tokens. Also, exchange the refresh token every time you get a new access token. This renewing process can be happing in the background (maybe using workers). So you don't need to invalidate tokens, It will be invalidated automatically after a few mins.
Recommend you to watch this: https://www.youtube.com/watch?v=rCkDE2me_qk
Store your refresh tokens in a database, with enough context to create a new JWT token (also expiry date, allowed IPs/regions/browsers ...etc) this database will be used only by your Auth service, and only when managing auth (login, logout, refresh access token).
Storing JWT in a database introduces a single point of failure for your microservices (Assuming you are using this architecture), if you're storing JWTs somewhere it would be a simpler implementation to just use session IDs and data.
Give each JWT token an ID (it's already in the default claims), and link that ID to a refresh token
when you invalidate a refresh token, broadcast an event to all your services telling them that any JWT with the token.JwtId is invalid. this invalidates all JWTs created by that token on all services (You can invalidate by token context as well, ex: user id to invalidate all tokens for a user that were created before X)
I'm building an app and an API endpoint using PHP(I know what you thinking!). My issue is that if I ask user for username and password on opening the app for the first time, since I can't store these details locally because they could be compromised. I'd send these through Post request to server then generate a token depending on whether the user is the right one. After getting response I must store this token locally right?
Yes!. there's expiration for the token. After the token is expired, I don't want to ask user for their name and password but want to access API still authenticating as that user. How will I do this?
If I use Oauth it's still the same procedure right? I should store something locally. won't that be compromised? I'm very confused.
How does other apps work. I'm sure they doing something in the background. They ask us for credentials only once and all subsequent API calls will be secured. Won't the token expire in that case or what?
Can i secure API calls without storing anything locally? I don't want API to be accessed from anywhere else but app.
Use android SharedPreferences. It should be very secure unless you deliberately expose it e.g. its accessible via an exported content provider missing the (android:exported="false") in the manifest. You can also use sqlite but there is no point of using a db table for one or two rows of data.You can also encrypt the user name and password to add one more security layer to protect rooted users.
Furthermore to protect the data in the network you should use ssl in the backend so no one can sniff the credentials.
How good practise is saving any other user info except JWT in localstorage or cookie after successfull login? (User profile object is already saved and encrypted in jwt payload sub part.) I need user profile object ready before initializing anything else in angular (for fetching user role, login status etc.).
If I save only JWT on client side i need one extra ajax request before app load to get user info from JWT decode on server side, because token secret is on server (only after full page refresh). Token is valid or invalid, so handling errors in this case is much easier.
If I save JWT and user profile object as a string in storage on client side then this is rendundant and user can change manually that object and app can go down.
I prefer saving only JWT in storage on client side after successfully login, but i need some advice, how organize code in that case? How fetch user profile object after full page refresh?
Please help.
The most secure solution is to store the JWT in an HTTPS-Only cookie, then make a request of the server to get the user object.
If you want to avoid that extra call to the server you will need to get creative. One approach I'm trying is storing the claims body of the JWT on the client - just the body, the signature is excluded. With the signature excluded the "token" is no longer a JWT and cannot be used for authentication, thus preventing the actual access token from being stolen out of local storage.
However this DOES assume two things about the claims body:
1) That the information is opaque and does not contain personally identifiable information (PII) about the user (local storage is vulnerable to XSS attacks).
2) Your Angular application does not leak sensitive information to the user if this object is modified in local storage (you should not store sensitive information in your Angular application, it should be protected by an API)
3) As with all cookie-based authentication strategies, you are protecting yourself against CSRF Attacks
I work at Stormpath and I recently wrote a blog post on this very subject: Token Based Authentication for Single Page Apps.
Hope this helps!
For the sake of simplicity, I would store just JWT and implement an extra ajax call to fetch the user profile.
But if you absolutely want to avoid this one call, you may consider using asymmetrically signed JWT instead of encrypted JWT and then extract data on the client side, assuming you control the creation of JWT.
I've got a backbone webapp, It consists into several form pages w/o any authentication.
All users are anonymous but i need a kind of logic to identifying them along the process.
Actually this is a comparator service.
I consume thru CORS a API in charge to deliver some contents, such as querying a Vehicule database, things related to a insurance policy and geo location...
No issues regarding consuming datas.
Now the question is more regarding how to save the anonymous users datas thru a multi-step form in the API.
The Goal would be, each time a user click on the next step, anonymous user datas will be save ( this is for analytics reasons ) and secure a bit the API with these POST requests.
As the webapp is in pure JS, i was thinking to do something like this :
if a cookie doesn't exist, i generate on the client side a session_id with with a js crypto lib and store this session_id into a new cookie ( with a expiration ) . Then a backbone model ( Session/Singleton ) will be in charge to store this session_id into a redis-cache store thru a Backbone.save(). Expiration of the Redis Key will match expiration of the cookie. Id attribute of the Session Model will be the session_id.
If the cookie exist. i'll fetch() the session from the API thru a getSession verb.
In this way i could keep tracking of every anonymous users to save the datas in my API. Do you think this is a good pattern or too naïve ?
Now, about securing the API... i'm stuck.
I was thinking about HMAC but if the secret key is stored on the client side ( backbone app ), shared for all users, someone could inspect the js client code, even uglyfied, and find the key...
I read many docs about this, but all are talking about a username/pwd/token scheme, in my case i've got only anonymous users...
Maybe, in the REST paradigm, anonymous users means that the datas are not sensitive.. .
Any advices ?
Thanks,
Anything that is stored client side is not secure. When it comes to an SPA, you usually authenticate a user using a username and password. Once the user is authenticated, you send a an Authorization token in the header of every request. If I am understanding your question correctly, you are worried about sensitive data being sent and inspected when the user is registering? If that is the case, you are best using a secure connection. I am curious to know how you think this is different for a non-backbone or SPA app? You would still be sending the data over HTTP, REST or non REST.
I use the Facebook Javascript SDK logging in User by retrieving a short-lived access token.
This short-lived access token is immediately sent to my app server, in order to get a long-lived one from it.
I think about 2 ways to deal with this token:
Storing it as a User's field (User being an Entity dealing only with authentication mechanism, not the same as UserProfile) in the database, so that it can only be associated to its particular user.
Do not store it in the database but replace the Facebook cookie containing the initial short-lived access token by the long-lived one.
I guess the first way is handy, since I wouldn't need to care about any cookies at all.
What would be the common good practice?