security

User Authentication with JSON Web Tokens

By Joshua Kemmerling
Architect, projekt202

Security today is more important than ever. Most people I know have online accounts at a bunch of different social networks or online retailers. Some of these websites require personal information and some don't. But every new website you create an account for increases your vunerability to being hacked. So, as web developers, we need to make security a priority during development. It doesn't matter if it's a mobile app, API or a client-side application. Security needs to always be taken into consideration.

Security is not only incredibly important today, but it's also easier to implement today than it was years ago. Developers have huge amounts of resources available to be able to learn about the most recent security standards and techniques, and most all of these techniques have been tested and proven. So, there isn't any good reason that a website should be lacking with its security.

There are many security concepts and techniques that exist, but I want to talk about JSON web tokens.

What are JSON Web Tokens, You Say?

JSON web tokens are a way to authenticate an API request. Each JSON web token is digitally signed, so JSON can be sent between clients securely. A JSON web token is made up of three parts -- header, payload and signature -- and looks like xxxxxx.yyyyyy.zzzzzz. They are very compact and can also contain necessary information in its payload, so you won't need to query a database as much as you normally would. JSON web tokens are stateless, so it is simpler for the server to authenticate API requests.

Let's see how we can use JSON web tokens in the real world.

Authenticate Users

In this first example, we are going to use JSON web tokens to authenticate the API request after a user has logged in. This is the most common situation where we at projekt202 use JSON web tokens. Note that all examples use Node and expressjs on the server.

1. Install jsonwebtoken Package

The first thing we need to do is install the required packages command in the command prompt:

[code language="shell"] $ npm install jsonwebtoken $ npm install express [/code]

2. Require the need packages

We need to require jsonwebtoken and the crypto library at the top of our file. The crypto library is built into Node, so it's already on your computer.

[code language="javascript"] var crypto = require('crypto'); var jwt = require('jsonwebtoken'); var express = require('express'); [/code]

3. Create the secret key

The next thing we want to do is create a secret string that will be used to digitally sign each token. This is what gives us the ability to trust JSON web tokens. When you create the secret key, it is extremely important that no one knows what the secret key is. If someone knows the secret key, then that person is able to create valid tokens to send to the server. To make sure that no one knows the secret key -- not even the developers that wrote the code -- we are going to use the crypto library and tell it to return us 20 random bytes, then we convert that to a string. We are going to set that value to a variable when the file loads up. This means that the only person that will be able to know the secret key will have to purposely write code to output the secret. You create the secret key like:

[code language="javascript"] process.env.jwtsecret = crypto.randomBytes(20).toString('hex'); [/code]

4. Create the token

The next step is to create the token. We do this by calling a function in the jsonwebtoken framework like:

[code language="javascript"] var token = jwt.sign({ role: 'admin', }, process.env.jwtsecret, { algorithm: 'HS512', expiresIn: 300 }); [/code]

The default algorithm used when creating the token is HS256. We want to replace that with HS512 for increased security. We also want to set an expiration time so that keys cannot live forever. In this situation, we are going to set the expiresIn to 5 minutes, but we have to give the time in seconds to the function. We are also using this to limit the amount of time a user can be logged in.

5. Attach the token to the response header

After the token is created, you want to send that token in the response header back to the client making the API request. Every API request will have the token in the header to verify the request. You will verify the token, then, if valid, create a new token and send it back to client to save for the next request. Using expresses, we can do this with middleware.

Read more about expressjs middleware here.

[code language="javascript"] app.use(function (req, res, next) { try { jwt.verify(req.get('x-token'), process.env.jwtsecret, { algorithms: [ 'HS512' ] }); } catch (e) { res.send(401);

return false; }

var token = jwt.sign({ role: 'admin', userId: 'h3bd-87db-23jh-8dh2-87d3-asd2-p2er' }, process.env.jwtsecret, { algorithm: 'HS512', expiresIn: 300 });

res.setHeader('x-token', token);

next(); }); [/code]

Full index.js file

Here is the entire index.js file for the server:

[code language="javascript"] var crypto = require('crypto'); var jwt = require('jsonwebtoken'); var express = require('express');

process.env.jwtsecret = crypto.randomBytes(20).toString('hex');

var app = express();

app.use(function (req, res, next) { try { jwt.verify(req.get('x-token'), process.env.jwtsecret, { algorithms: [ 'HS512' ] }); } catch (e) { res.send(401);

return false; }

var token = jwt.sign({ role: 'admin', userId: 'h3bd-87db-23jh-8dh2-87d3-asd2-p2er' }, process.env.jwtsecret, { algorithm: 'HS512', expiresIn: 300 });

res.setHeader('x-token', token);

next(); });

app.get('/', function (req, res) { res.send('Hello World!'); });

app.listen(3000, function () { console.log('Example app listening on port 3000!'); }); [/code]

More to Learn

This is a simple version that we use to authenticate users. I encourage you to customize this to your needs and read more about JSON web tokens. A good place to start is jwt.io. The site has more information and a way to test your tokens.

Look for another article in the near future on how to use JSON web tokens to authenticate application access to your API.

Stay up-to-date on projekt202 news, events and upcoming articles. Follow us on LinkedIn, Twitter, Facebook,YouTube and Instagram.

Five Ways to Make Software Unpleasant via Security

By Josh Christopher
Senior UX Designer, projekt202

Originally published in Medium

Rising awareness and willingness to address issues with Enterprise Software, the popularity of UX in the health care industry (HIPAA) and frequent hacks of personal private information online have led to a fear-fueled pattern when it comes to site security. Be not mistaken: fears are valid and loss of sensitive information could lead to much more than bad PR for a company. There are many real instances that could lead to substantial fines even if a company does not ever even “lose” information.

The pattern is that companies are taking their responsibility of being a secure resource for their users and simply passing that burden and liability back onto their users by creating overly-complex layers of access. This in turn limits the users' ability and desire to function with the service at all. These companies are rendering their software so secure that even the intended users are unable to access it.

Below are five ways to frustrate your users via security.

1. Implement extensive password rules

I understand the concern at a high level: "We don’t want people’s passwords to be hacked easily.” The issue with passwords, though, is this: on average, we each have about

25 accounts

that require passwords. Your users are naturally going to use a convention that fits with the

eight other passwords

they plan to type in on that same day. If you stray from that convention and force your users to make their passwords more difficult, you are making it harder for your users to get to you when they need you most. Lastly, even without more complex rules,

password recovery

is the number-one request for services that don’t have single sign-on capabilities.

Complex password rules make the job of creating a password much more difficult, too. Multiple failed attempts at complex password creation will have measurable impacts to your throughput. Likely, it also guarantees the password will be written down or saved in a place that is far more accessible than just being stored in your users’ brains.

Validation of the requirements can assist the users in first creating their passwords. Also, a password strength meter on password creation notifies users when they are at risk with too simplistic a password. Or, try not making users create a new password at all; allow login and account creation via social media.

The best solve altogether for the user may be to implement two-factor authorization as both a rebuttal and solution to the fear of being hacked. In addition, why have a maximum number of characters at all in a password? If your users are concerned about being hacked, they should be able to make their passwords the first 90 characters of π if they want.

2. Force users to reset their passwords

The problem for businesses is still password vulnerability. The fact is, though, that banks don’t even do this. It is not common outside of Enterprise Software. Much of the rationale for the first issue is also applicable for why this is no good for users. It creates the need for users to write down their passwords on little Post-its and paste them right onto their monitors.

Additional things to consider instead of a password are tokens or biometrics (iris scan, fingerprint ID, heartbeat). If it is Enterprise Software, a USB key could potentially be a better experience. Mainly, try really hard not to expire the passwords, because interrupting users' flow can have devastating effects. In e-commerce, 75% of users won’t complete a purchase if they have to first recover/reset their passwords.

3. Put CAPTCHA  —  everywhere

I understand the concern to an organization: "We need to watch out for malicious bots.” But oh, the problems it introduces for users. It increases form errors, causes poorer conversion, is difficult and is inconsistently branded (which can make it look like a security issue). Most are not tablet/mobile friendly.

If you need a mobile-friendly version, then reCAPTCHA isn’t awful. An even better solution is the Honeypot, a hidden form field that humans cannot see, but robots find irresistible. The biggest issue I see with Honeypot CAPTCHA is that there doesn’t seem to be a great solve for accessibility, but CAPTCHA in general is not super accessible either so we still need to implement a fix for this part of it.

4. Lock out after X number of failed login attempts

So, hypothetically speaking, a company suspects someone may be trying to hack into your account. However, they may have also made your password insanely difficult for you to remember and also included additional steps for you to retrieve access to your account.

Obviously, I am exaggerating, but I suppose I would be OK with this as long as there is at least a simple software solution in place for me to reclaim access to my account. If you plan to force me to call or email someone to get access to my account, plan on not seeing me again.

Best solve for this is also two-factor authorization.

5. Have security questions (lots of complex ones, too)

First, let me say it just simply is not secure. This is one way all the “unnamed” celebrities' phones are getting hacked. People are guessing/finding the answers to these questions to gain access to their private information.

Make the questions more difficult and random, right? No, not right. My answer to “Who is your favorite cousin's neighbor?” may change between now and when I need it. Also, it will take me awhile to find a question in a list of 10 that I feel I could actually answer later. Users have told me they created workarounds in which they answer the security question with its last word to avoid dealing with the complexity of this feature.

Example: Question: What is your mother’s maiden name? Answer: name

The best solution is to verify a forgotten username or password via another form of contact, like phone or email.

A Bonus Bargaining Tip

If you are currently in talks about site security with your client/company, another thing to consider is the implementation of SHOW/HIDE passwords in form fields. It could have a solid impact on the throughput and usability of your software.

In Conclusion

Exceeding users' tolerance to security results in them having to work against you and your security parameters to make the software easier to use. They will do things like write down passwords, use predictable shortcuts to remember answers and reset expired passwords with weak flavors of previously used passwords. Overly-complex security parameters may actually result in less secure software. It's best is to come up with options that are still secure, but don’t simply pass complexity on to customers.