I am working on a web application that is using Go in the backend and JWT based authentication. When users logged in, I send them access token with a short expiration time and a refresh token with a long expiration time. Both of these tokes includes username as their payload. They are created with different secrets. My question is about log out. When a user sends a log out request, I want to invalidate it's refresh token so that they are needed to log in again after log out. For solution, I am going to store that refresh token in a blacklist table in my database. My question is that should I need to hash that refresh token before storing it in the database. Thanks.
One of the standard JWT claims (RFC 7519 §4.1.7) is "jti", which is a unique identifier for the token. If you include a unique identifier in your refresh token, then it's enough to store the "jti" and "exp" (expiration) claims in the database. (I'd default to using ("github.com/satori/go.uuid").NewV4 to generate the "jti" as a random UUID, and that's internally backed by the "crypto/rand" random-number generator.)
Now if you're presented a refresh token, you can do your usual checks that it's correctly signed and unexpired, and then look up the "jti" in the database. If it's not on the blacklist, then it's good for reuse. You only need to keep "exp" in the database to know when it's safe to clean records out. Since the "jti" is just a random identifier, you can't get back from the "jti" to any identifiable information so there's no particular need to hash or encrypt it.
If you don't have a "jti" and can't add one, I'd probably either hash the token or just keep a copy of the claims. Partly this is for space reasons, and partly you don't want to store something that's actually a valid credential. Keep enough information that you can uniquely identify a token; possibly the "sub" and "exp" time together are enough information (if two tokens issued to the same subject expiring at the same second are indistinguishable).
Related
I am looking to implement SSO in all my future php/angular applications. I see there are services (Auth0, oauth.io, etc) that are sort of the middle man of an SSO app and there are protocols such as OAuth 1.0/2.0 but in regards to creating a custom SSO solution (using aforementioned OAuth protocols, I assume), I am a little foggy on the complete flow of the process.
What I do get:
App gets Access Token
(optional) App validates Access Token
App (with Access Token) gets access to a particular API and returns result. For
example, Facebook profile information.
What I don't get:
What to do with that information once I have it. Do I retain the access token and request information from the API source each time they login? How do I relate my own application data to the API data? Would I create a different kind of user record that just contains the access token and application's userid?
Do I retain the access token and request information from the API source each time they login?
If the token does not expire, you can hold on to it in a data store and use it with each request. Many times, though, the token will expire, and you need to request a new one each time you start a session. In this case you'd probably store the token in memory instead of a permanent storage location.
How do I relate my own application data to the API data?
I think we'd need to know a little more about your application to answer this question.
Would I create a different kind of user record that just contains the access token and application's userid?
Again, we'd probably need a little more information about your application. If you were persisting the token (in the case that it doesn't expire), then you need to make some considerations about how you want to store it. If not, you can probably just put it into a local variable or session.
When I link an account with a third party they send an access token as well as the user's username.
Alexa automatically saves the access token and gives it with each request. How can I get it to save the username as well?
This is intentionally not supported in order to protect the user's privacy. That is a good thing.
Alexa does provide a userID with each call. This id is specific to each user, and the same every time they use your skill. It doesn't give you any personal information, but it does allow you to save information for each user to your own database. You can associate that user's data with the userId and recall it every time they use your skill.
So for example, you can ask the user for a name, save it to your database keyed by the userId, and recall it at a later date using the userId.
Search on "alexa user information" for more info, for example this post.
Just encode the user name and/or any other information to the token itself.
For example you can use JSON Web Token - https://jwt.io/ - wich is an RFC 7519
It is intended exactly for the use case when you you don't want to make an additional request(s) just to retrieve some rarely changing info.
Regards caching/refreshing you can issue token for limited amount of time (an hour?).
o/
I'm working on a smaller app, and its going pretty well so far. I talked with a friend about it and he suddenly made me realize something. How do i make sure a user is only able to query his own data from a Database in the cloud?
Its a very simple app, where you can create a user and make some personal shopping lists.
I thought about a couple of options, but I'm not sure what is the right direction to take - or even if any of them is the right one.
The username/id & password is stored locally and appended to the request, and checked against the DB every time.
A token is generated, saved both in the DB & stored locally as a "active" session, and every time a request is send, the token is appended to the request and checked.
...?
I'm sorry if i placed this topic have the wrong tags, since i was not 100% sure where they should be placed.
Well, from your description it seams that you are working on a "no backend" app. If it is the case I suggest you to take a look to Firebase since it will solve all your concerns about authentication and user authorization.
If your would like to use a more custom approach, simply consider that appending the username and a passowrd to a request is always not recommended and since you are using a token is also unnecessary.
Now, returning to the question, i will give you my vision related to contexts where an authentication token is used and thus a backend is needed:
when you log-in a user, you produce a token that is function of the user id
each user request must contain that token
the backend can extract the id of the user that submitted the request from the appended token
a policy or a specific condition will check that data that is going to be retrieved must belong to the user whose id has been extracted.
Hope this could help you
I'm intending on using a hash to generate a verification token for verifying email addresses. The hash would be generated like so:
email:username:salt
The hash is generated with the SHA256 algorithm and the same salt is used for each token generated.
The alternative, and more commonly used, method is to generate a one time UID which is stored in the database and acts as the verification for the new email address.
My question is: is this an efficient (taking processor and disk utilisation etc.. into account) way of achieving the generation of a token for email validation.
The whole purpose of email verification tokens is to generate a token from your secure web server, and email that token out to someone so that they can click a link which contains that token, so you can then verify their account.
The important things to keep in mind:
The token must be impossible for the end-user to reproduce, otherwise it can be faked.
The token needs to be cryptographically signed by your web server (ideally), so that the CLIENT knows this is a valid token. This also is important because when the user sends this token BACK to your server, you can verify that YOUR server is the one that created it.
The token needs to be expireable: you should be able to 'expire' this token if it is not used within a certain amount of time: 24 hours, 3 days, etc.
For this reason, I would not recommend the approach you're taking.
Instead, I would use a JSON web token (this is an ideal use case for them). This other SO question has a decent summary.
Using a JWT will let you:
Create the token on your web server.
Set an 'expirey' date on this token so it can't be used after a certain time limit you specify.
Encode any user-specific data in the token you want: usually a user ID or something similar.
When the user sends the token back to your web server, a JWT will:
Guarantee that the token was generated by your server and not someone else maliciously.
Guarantee the token is still valid (in terms of timestamp).
Guarantee the token hasn't been tampered with.
Let you view the previously encoded token data (user ID / etc).
I hope this helps =)
What you're doing is somewhat secure.
I would refer to your salt though as a key - you are generating a keyed hash. Ensure that you generate a key with sufficient entropy. I would recommend a strength of 128 bits generated by a CSPRNG.
Some keyed hashes generated in this manner are vulnerable to a length extension attack. That is, if an attacker has generated a validation token for foo#example.com then they will be able to work out the hash for foo#example.com.example.org. This is because the output of a hash algorithm also betrays its state. To mitigate this, you could use the HMAC algorithm.
Your current approach also has the limitation that an email address always has the same token. If an email address expires (say Bob Smith with email bobs#example.org is fired from his job at Example Organisation, he will know the verification code that the next Bob S. will get when he starts working for Example Organisation). Whether this is any risk to your application is for you to decide. To mitigate this, you could use JWTs instead, which will enable you to put an expiry date into the token that can be validated. JWT's HS256 algorithm also uses an HMAC, solving that problem too.
Using keyed hashes should be efficient, and doesn't have the storage, maintenance and overheads of database lookups.
By UID do you mean UUID?
Remember that:
the purpose of a [UUID] is to be globally unique, not to be unguessable.
and
[UUIDs] are designed for uniqueness, not for security.
You would be better off generating an 128 bit token on the fly using a secure source of entropy (say another CSPRNG). You may want to hash these (without salt) on the server-side using SHA-256 to prevent any data leakage vulnerability from meaning an attacker can validate any email address.
I have the following code in my angular app declaration - an API key for Facebook (to implement Share button):
.run(function($FB){
$FB.init('9xxxxxxxxxxxx94');
})
So i know the general answer to this - 'API keys should be kept on the server side', however I don't see how i actually implement this.
The share call-method is made on the front end, so even if my server kept the API key and sent it, surely it's still visible on the front end, else how would the share button work?
So my question, how do I hide that Facebook API Key?
Thanks.
Requesting the key
The first thing that happens is that the client will request a key. This will only happen on certain pages like the sign up and log in pages. The idea here is that we want to make sure that only users browsing with a known client (in this case the official website or core client as it’s called) are allowed to take actions like creating or authenticating a user.
So when the client app requests the login page the server generates a unique token based on information sent in the request. The information used is always something the server knows, something the client knows, and something both know. So for example the server can generate a unique key based on User agent + current time + secret key. The server generates a hash based on this information and then stores a cookie containing only the hash on the client machine.
Setting permissions
At this point our key really isn’t a key anymore. It has been transformed into an access token. The server should then take this access token and store it for later retrieval. You can put the key in a database but since data of this type needs to be retrieved often I would suggest using a key-value store like Redis to cut down on database reads/writes and boost performance.
When you store the token you should also store a separate piece of data to indicate what permissions are associated with the token. In this case our token is acting only as a way to register and authenticate users so we store it next to a value that indicates who the token belongs to (the app’s web UI) and what permissions it has (limited to create and authenticate users). We treat it just like we would any other API client that way we can capture stats and control how it is used.
Authorizing a request
When the client then makes the POST request to create a new user or log in the server will check to see if the client sent an identifying cookie along with the request. If not, we reject the request. If it does send the cookie, the server should once again generate the hash using the values used previously (these values are either already known or sent with the request anyway so we’re not really taxing the server much) compare it to the cookie being sent to us, and if the values match allow the request to proceed.
Sources - Securing API Keys
OR
Simply send a request to your Server and let him handle your request with the hidden API-key and just return the result of your request to your front-end.