Categories
Express JavaScript Nodejs

Verifying JSON Web Tokens with Express-JWT

With the use of single-page apps and API-only back end, JSON web tokens (JWTs) have become a popular way of adding authentication capabilities to our apps.

In this article, we’ll look at how to verify JSON web tokens with Express-JWT.

Installation

express-jwt is available as a Node package. To install it, we run:

npm install express-jwt

Usage

We can use the jwt function that’s included with the express-jwt package to verify a token.

jwt is a middleware function, so we don’t have to create our own middleware to verify the token.

For example, we can use the jwt function as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();
const secret = 'secret';
app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, secret);  
  res.send(token);  
})
app.get('/protected', jwt({ secret }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

In the code above, we called jsonwebtoken.sign to issue a token in the auth route.

Then we can call the protected route by putting Bearer and then our token in the Authorization request header.

An example Authorization header would be:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1Nzk0NzczMDd9.QW7FOvyJQ36dir0199nJTv07VhlNo9\_cItGTkdyJeK8

If the token isn’t valid or isn’t present, then we would get an error.

We can also check other fields like audience or issuer as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();
const secret = 'secret';  
const audience = 'http://myapi/protected';  
const issuer = 'http://issuer';
app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, secret, { audience, issuer });  
  res.send(token);  
})
app.get('/protected', jwt({ secret, audience, issuer }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

In the code above, we added audience and issuer to the object in the 3rd argument of the sign method call, which holds the options that we want to add to the token issued.

Then in the protected route, we added the jwt middleware with the audience and issuer in the options object that we passed into jwt .

If the token has a secret , audience , and issuer that match what the code has, then the protected route returns the protected response. Otherwise, we get an error.

We can verify a token that’s generated with a Base64 encoded secret as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();
const secret = 'secret';
app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, new Buffer(secret, 'base64'));  
  res.send(token);  
})
app.get('/protected', jwt({ secret: new Buffer(secret, 'base64') }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

In the code above, we have the new Buffer(secret, ‘base64’) passed to the second argument of the sign method, which generates a token from a Base64 encoded secret.

Then in the protected route handler, we can call the jwt middleware function with the same secret to verify the token.

To verify a token generated with an RSA private key, we can write the following:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const fs = require('fs');  
const app = express();
const publicKey = fs.readFileSync('public.pub');
app.post('/auth', (req, res) => {  
  const privateKey = fs.readFileSync('private.key');  
  const token = jsonwebtoken.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });  
  res.send(token);  
})
app.get('/protected', jwt({ secret: publicKey }), (req, res) => {  
  res.send('protected');  
})
app.listen(3000, () => console.log('server started'));

The token is generated in the auth route by reading the private key from a file on the file system and then using that to sign the token with the sign method.

Then we can use the public key that corresponds to the private key that was used to generate the token to verify the token by writing:

jwt({ secret: publicKey })

To access the decoded token, we can use the req.user property as follows:

const express = require('express');  
const jsonwebtoken = require('jsonwebtoken');  
const jwt = require('express-jwt');  
const app = express();  
const secret = 'secret';app.post('/auth', (req, res) => {  
  const token = jsonwebtoken.sign({ foo: 'bar' }, secret);  
  res.send(token);  
})app.get('/protected', jwt({ secret }), (req, res) => {  
  res.send(req.user);  
})app.listen(3000, () => console.log('server started'));

In the protected route, we returned req.user as the response. Then we should get something like:

{  
    "foo": "bar",  
    "iat": 1579478314  
}

in the response content.

We can change what property the decoded token is attached to by setting the requestProperty property as follows:

app.get('/protected', jwt({ secret, requestProperty: 'auth' }), (req, res) => {  
  res.send(req.auth);  
})

Then we get the same response as the previous example.

Conclusion

We can use the express-jwt middleware to verify our JSON web tokens.

It takes a secret and other token options like audience and issuer and then sets the decoded token to the Express request object if verification is successful.

If verification isn’t successful, then an error is returned.

It supports both symmetric and asymmetric crypto algorithms.

Categories
JavaScript Vue

Vue.js Templates: Modifiers and Shorthands

Vue.js is an easy to use web app framework that we can use to develop interactive front-end apps.

In this article, we’ll look at modifiers for directives and some useful template shorthands.


Modifiers

Modifiers are used for binding a directive in a special way.

Event modifiers

For example, the .prevent modifier for the v-on directive will automatically run event.preventDefault on the event handler function that’s set as the value.

The .prevent modifier can be used as follows:

<form v-on:submit.prevent="onSubmit"> ... </form>

Then, event.preventDefault() will be run when the onSubmit handler is run, before the rest of the code for onSubmit is run.

Other event modifiers include:

  • .stop
  • .capture
  • .self
  • .once
  • .passive

.stop runs event.stopPropagation() before the rest of the event handler code is run.

.capture lets us capture the event. That is, when we run the event handler in an inner element, then the same event handler will also run in the outside elements.

For example, if we have the following in src/index.js:

And the following in index.html:

Then, when we click Click Me, we’ll see the “clicked” alert box since the onClick handler is called on the parent div element.

.self will only trigger the event handler if the event.target is the element itself.

.once will trigger an event handler at most once.

For example, if we have the following in src/index.js:

And the following in index.html:

Then we only see the “clicked” alert box once even though we click “Click me” multiple times.

.passive will set the addEventListener’s passive option to true. passive set to true means that preventDefault() will never be called.

It’s used for improving performance on mobile devices.

Model modifiers

v-model has modifiers. They’re:

  • .lazy
  • .number
  • .trim

The .lazy modifier will make the model sync after the change event instead of the input event.

For example, when we have src/index.js:

new Vue({  
  el: "#app",  
  data: { msg: "" }  
});

And write the following in index.html:

Then we only see msg rendered when we move focus away from the input.

The .number modifier will automatically cast whatever is inputted in an input to a number.

For instance, if we have the following in src/index.js:

new Vue({  
  el: "#app",  
  data: { num: 0 }  
});

And the following in index.html:

Then we’ll get a number for num.

The .trim modifier will trim whitespace from whatever is inputted.

We can use it as follows:

<input v-model.trim="msg" type="number" />

Shorthands

There are shorthands for some directives.

v-bind

We can shorten v-bind: to :. For example, we can rewrite:

<a v-bind:href="url">Link</a>

To:

<a :href="url">Link</a>

We can also put in a dynamic argument if we use Vue 2.6.0 or later:

<a :[key]="url">Link</a>

v-on

We can shorten v-on: to @.

For example, we can shorten:

<a v-on:click="onClick">Click me</a>

To:

<a @click="onClick">Click me</a>

Since Vue 2.6.0, we can also use dynamic arguments as follows:

<a @[event]="onClick">Click me</a>

: and @ are valid characters. Also, they won’t appear in the final markup. Shorthands are totally optional. But we’ll appreciate them when we have to type them in a lot.


Conclusion

Some directives have modifiers that are associated with them.

The v-on directive has multiple modifiers for controlling how event handlers are called.

Also, the v-model directive has some modifiers to let us convert input to numbers automatically or trim whitespace from inputs.

v-on and v-bind also have shorthands. v-on: can be shortened to @, and v-bind: can be shortened to :.

Directive arguments also work with shorthands.

Categories
JavaScript Rxjs

More Useful Rxjs Transformation Operators

RxJS is a library for reactive programming. Creation operators are useful for generating data from various data sources to be subscribed to by Observers.

In this article, we’ll look at some RxJS transformation operators like concatMapTo, expand, exhaust, and exhaustMap operators.

concatMapTo

The concatMapTo operator takes the source value of the Observable and maps each value to the same inner Observable.

It takes up to 2 arguments. The first is the innerObservable, which is the Observable to map each value from the originating Observable to.

The second argument is a resultSelector function to let us pick the results.

Each originating Observable’s emitted value is mapped to the given innerObservable regardless of the source value. Then flatten those resulting Observables into one Observable. which is the returned Observable.

Each new innerObservable’s emitted are concatenated together with the other ones’ values.

If the source values arrive endlessly and faster than the corresponding inner Observables can complete then it’ll result in memory issues since there’ll be a large amount of data amassed waiting to be subscribed to.

For example, we can use it as follows:

import { fromEvent, interval } from "rxjs";  
import { take, concatMapTo } from "rxjs/operators";
const clicks = fromEvent(document, "click");  
const result = clicks.pipe(concatMapTo(interval(1000).pipe(take(5))));  
result.subscribe(x => console.log(x));

The code above will get the click events from the document and then emit 0 after 1 second, then wait for another second and emit, up to 4.

exhaust

The exhaust operator converts a higher-level Observable, which are Observables that emits Observables, into the first-order Observable by emitted inner Observables while previous inner Observable hasn’t been completed.

The result would be that the values from all the Observables are flattened and emitted by one Observable, which is the one returned by this operator.

For example, we can write:

import { interval, of } from "rxjs";  
import { exhaust, map, take } from "rxjs/operators";
const observable = of(1, 2, 3);  
const higherOrder = observable.pipe(map(ev => interval(1000).pipe(take(5))));  
const result = higherOrder.pipe(exhaust());  
result.subscribe(x => console.log(x));

In the code above, we have an observable Observable that emits 1, 2, and 3. The values emitted by observable are mapped to inner Observables using the map operator into interval(1000).pipe(take(5) .

Since the inner Observables that aren’t completed are dropped by the exhaust operator, we’ll get that interval(1000).pipe(take(5) is only emitted once since only the first instance of it is started. Then we get that a number is emitted every second, starting with 0 and stops at 4.

exhaustMap

The exhaustMap operator also takes the first inner Observable that are mapped from the originating Observable like the exhaust operator. The difference is that it takes a function that lets us map the values of the origination Observable’s emitted values into another Observable, but only taking the first emitted Observable by this operator.

For example, if we have the following code:

import { interval, of } from "rxjs";  
import { take, exhaustMap } from "rxjs/operators";
const observable = of(1, 2, 3);  
const result = observable.pipe(exhaustMap(ev => interval(1000).pipe(take(5))));  
result.subscribe(x => console.log(x));

We get the same result as exhaust, but we don’t have to pipe and map the emitted values of observable into a new Observable. Instead, we combined everything together with the exhaustMap operator.

expand

The expand operator recursively projects each source value to an Observable which is then merged into the output Observable.

It takes 3 arguments, which is the project function, which applies to the items emitted by the source Observable or the output Observable and returns a new Observable.

The second argument is the concurrency, which is an optional argument for the maximum number of input Observables being subscribed to concurrently. It defaults to Number.POSITIVE_INFINITY .

The last argument is the optional scheduler object, which is the scheduler we can use to time the emission of values.

One simple example usage of this operator would be as follows:

import { of } from "rxjs";  
import { expand, delay, take } from "rxjs/operators";
const powersOfTwo = of(1, 2, 3).pipe(  
  expand(x => of(x).pipe(delay(1000))),  
  take(10)  
);  
powersOfTwo.subscribe(x => console.log(x));

In the code above, we have the of(1, 2, 3) Observable, which have the emitted values pipe d to the expand(x => of(x).pipe(delay(1000))) Observable. Then the first 10 values are taken from the Observable returned by expand, which takes the of(1, 2, 3) Observable’s emitted values and emit them repeatedly until we have 10 values emitted and each group is emitted after waiting 1 second.

This is because we specified of(x) which takes the of(1, 2, 3) values and then get then emit them without making any changes. pipe(delay(1000)) delays the emission of each group of values 1, 2 and 3 one second apart.

This should result in the following output:

1  
2  
3  
1  
2  
3  
1  
2  
3  
1

Conclusion

concatMapTo operator takes the source value of the Observable and maps each value to the same inner Observable.

The exhaust operator converts an Observable which emits Observables and then emit the values from the first inner Observable and discard the ones that haven’t finished emitting.

The exhaustMap operator also takes the first inner Observable then map them into inner Observables, which then have the values emitted.

Finally, the expand operator recursively projects each source value to an Observable which is then merged into the output Observable and emitted.

Categories
Flow JavaScript

JavaScript Type Checking with Flow — Typeof Types

Flow is a type checker made by Facebook for checking JavaScript data types. It has many built-in data types we can use to annotate the types of variables and function parameters.

In this article, we’ll look at typeof types, which are types that are derived from other values.

The JavaScript Typeof Operator

In JavaScript, the typeof operator is mostly useful for checking the type of primitive values. For example, it works for numbers, booleans, and strings:

typeof 2 === 'number'  
typeof true === 'boolean'  
typeof 'abc' === 'string'

For objects, it always returns 'object' :

typeof { foo: 'abc' } === 'object'

Flow’s Typeof Operator

Flow’s typeof operator is much more useful. It can be used to return the value of any type.

For example, it can get the type for numbers as follows:

let num = 42;  
let num2: typeof num = 3.14;

It’ll fail when we assign values of any other type to it, like the following:

num2 = 'foo';

The benefit of Flow’s typeof operator is that it can also be used for objects. For instance, if we have the following object:

let obj = { foo: 1, bar: true };

Then we can use the typeof operator to assign the obj object as a type of another object as follows:

let obj2: typeof obj = { foo: 1, bar: false };

As long as we have all the properties of obj with the same data type, then it satisfies the requirement of the typeof obj type.

We can do the same for arrays as follows:

let foo = [1, 2, 3];  
let bar: typeof foo = [3, 2, 1];

typeof foo will infer that the type of foo is a number array, so we can assign another number array to bar .

Type Inference

The typeof operator does type inference implicitly. When we use literal values with Flow, then the inferred type is the primitive that the value belongs to.

For example, 1 would be a number . We can override the inferred type by explicitly asserting the type of variable we define as follows:

let num1: 1 = 1;

Then assigning num1 to anything other than 1 will fail:

let num2: typeof num1 = 3;

The code above will give us an error.

Typeof’s Nominal Type Check

Like other parts of Flow, the typeof operator also checks type nominally. This means that it checks the name rather than the structure. Therefore, even though 2 types have the same structure, but when their names are different, then they’re considered different.

For example, if we write:

class Foo {  
  foo(val: number) { }  
}

class Bar {  
  foo(val: number) {  }  
}

Then the following assignment would work:

let x: typeof Foo = Foo;

because both types have the same name, but:

let y: typeof Foo = Bar;

would fail even though Foo and Bar have the same structure since the have different names.

With Flow’s typeof operator, we can identify types of objects in addition to primitives. It’s consistent with Flow’s nominal type system in that it also checks the name by its name instead of the structure.

Also, the typeof operator can infer types from the data that’s assigned to a variable. For example, if a variable is a number array, then using the typrof operator on that array will return number array as the type.

Categories
Express JavaScript

Guide to the Express Response Object — Sending Things

The Express response object lets us send a response to the client.

Various kinds of responses like strings, JSON, and files can be sent. Also, we can send various headers and status code to the client in addition to the body.

In this article, we’ll look at various properties of the response object, including send , sendFile , and sendStatus .

Methods

res.send([body])

We can use the res.send method to send an HTTP response.

The body parameter can be a Buffer object, string, a plain object or an array.

For example, we can send a binary response by writing:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.send(Buffer.from('foo'));  
})  
app.listen(3000);

To send JSON, we can pass in an object:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))app.get('/', (req, res, next) => {  
  res.send({ foo: 'bar' });  
})  
app.listen(3000);

We can also send HTML by passing in a string:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))app.get('/', (req, res, next) => {  
  res.send('<p>foo</p>');  
})  
app.listen(3000);

We can send the response code in addition to the send method:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.status(404).send('not found');  
})
app.listen(3000);

We can set the response header before sending our response:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.set('Content-Type', 'text/html');  
  res.send(Buffer.from('<p>foo</p>'))  
})  
app.listen(3000);

send also works with an array:

const express = require('express')  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.send([1, 2, 3]);  
})
app.listen(3000);

Then we get [1,2,3] .

res.sendFile(path [, options] [, fn])

We can use the sendFile to send a file with various options specified in the options object.

An absolute path is required for the path for sendFile to work.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  const options = {  
    root: path.join(__dirname, 'files'),  
    dotfiles: 'deny',  
    headers: {  
      'x-timestamp': Date.now(),  
      'x-sent': true  
    }  
  }  
  res.sendFile('foo.txt', options);  
})  
app.listen(3000);

The code above sets the root path in the options so that we don’t have to construct the absolute path every time we call sendFile .

The following properties can be added to the options object:

  • maxAge — sets the max-age property of the Cache-Control header in milliseconds or a string in ms format
  • root — root directory for relative filenames
  • lastModified — sets the Last-Modified header to the last modified date of the file on the OS. Set to false to disable it.
  • headers — an object containing HTTP response headers to serve with the file.
  • dotfiles — option for serving dotfiles. Possible values are allow , deny , or ignore .
  • acceptRanges — enable or disable accepting range requests
  • cacheControl — enable or disable setting Cache-Control response header
  • immutable — enable or disable immutable directive in the Cache-Control header. If it’s enabled, the maxAge option should be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of maxAge option to check if a file has changed.

We can also pass in a callback to handle errors as the last argument:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  const options = {  
    root: path.join(__dirname, 'files'),  
    dotfiles: 'deny',  
    headers: {  
      'x-timestamp': Date.now(),  
      'x-sent': true  
    }  
  }  
  res.sendFile('foo.txt', options, err => next(err));  
})  
app.listen(3000);

res.sendStatus(statusCode)

We can send an HTTP response status code with this method. We just have to pass in a number.

If an unsupported status code is specified the code will still be sent and a string version of it will be sent in the response body.

For example, if we have:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.sendStatus(200)  
})  
app.listen(3000);

Then we get back OK .

If we write the following:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.sendStatus(900)  
})  
app.listen(3000);

We get 900 since we sent an unsupported response code.

Conclusion

We can send responses in various ways with Express. The most generic one is send , which lets us send both textual and binary data. We can set headers to indicate what we’re sending.

sendFile sends a file response with the absolute file path of the file on the server. We can specify various options for the file we send.

The sendStatus method lets us send an HTTP response code only. We can use it to send both supported and unsupported response codes.