Use TypeScript to Create a Secure API with Node.js and Express

In this tutorial you’ll use TypeScript to create a Node.js API with Express.

You’ll learn how to…

  • Set up webpack’s Hot-Module Replacement (HMR)
  • Create data models and services
  • Create endpoints with error handling
  • Secure the API with authentication and authorization
  • Add Role-Based Access Control (RBAC)

Brought you by myself, @dan-auth0 :cowboy_hat_face:

Read on :nerd_face: Node.js and TypeScript Tutorial: Build a CRUD API

3 Likes

Dan, I had done this exercise before with the rbac.middleware.ts file, I noticed we are now using a permissions.middleware.ts using jwtAuthz from Auth0. Can I still access the token coming from Auth0 using jwtAuthz?

is using jwtAuthz a best practice in this instance?

We are in production and I was just reviewing the code and ran into this.

Thank you

Adan

1 Like

Hey there @adan I’m sure Dan will cover that once he’s online!

Welcome to our Auth0 Community. Thank you for reading the tutorial :slight_smile: I’ll be researching this for you today :muscle:

Adan,

You can still access the access_token through the req.user object :slight_smile: My colleague @holly suggested that using the express-jwt-authz gave us a simpler implementation of the middleware function that checks for permissions.

It’s not so much as that using that package is a best practice but rather that it gives you the same outcome with less code :muscle:

If you prefer, you can still use the previous middleware function. Here’s the file code in case you need it to compare. This should be latest version. Does it match with what you have?

fyi, webpack.config.ts

nodeExternals({
whitelist: [“webpack/hot/poll?100”]
})
],

had to change ‘whitelist’ to ‘allowlist’ :

1 Like

Thanks for reporting that @johnguruwp!

Howdy, @johnguruwp ! Welcome to the Auth0 Community and thank you for reading the blog post.

Yes! I was actually following this tutorial yesterday for an internal project I am working on and got the error! I am working on the update. Thank you for bringing it up.

By the way, I am curious on your perception: Do you find the early introduction of Webpack Hot Module Replacement useful or do you think that should be left as an optional step at the end?

Dear Dan,

Ran into problems. Am quite a newby. npm start worked “listening on port 7000”

FYI, first of all on my W10 machine I had to give the command “Remove-item alias:curl”
to get rid of:
"Invoke-WebRequest : Missing an argument for parameter ‘InFile’. Specify a parameter of type ‘System.String’ and try again.
At line:1 char:34

Looked over my code multiple times, did some research, but still get the 404 not found (also added the middleware error handling).

After curl http://localhost:7000/items -i

I get following, any suggestions to track the error?

HTTP/1.1 404 Not Found
Content-Security-Policy: default-src ‘none’
X-DNS-Prefetch-Control: off
Expect-CT: max-age=0
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Download-Options: noopen
X-Content-Type-Options: nosniff
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: no-referrer
X-XSS-Protection: 0
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 144
Date: Tue, 01 Sep 2020 15:10:11 GMT
Connection: keep-alive

Error
Cannot GET /items
1 Like

Hello, Bas. Welcome to the Auth0 community and thank you for reading this blog post.

Could you try making your requests using PowerShell on Windows using the instructions in this blog post, please:

Dear Dan,

Did open a terminal in Visual Code which is a Windows Powershell and in a separate Powershell window. None worked. Have to give the command remove-item every time I open the terminal window.

1 Like

Hello, Bas. Not sure what could be happening. The code is working as intended on my end. Sounds like there is some type of conflict in your system with the requests not going to the app. Can you try accessing the GET request using your browser, please? :slight_smile:

Hi Dan! Thank you for the tutorial, it’s great so far. However I’ve run into an issue in the “Signing In” section.

When I open the WAB Dashboard and sign in, I’m signed in successfully but the application does not update as expected: “Once you sign in, the user interface of the WAB Dashboard changes: A user tab is now displayed below the Sign Out button.”

The Sign In button does update to “Sign Out” but I do not see a user tab below it.

I’m not sure exactly what’s going on here. I’m happy to provide any additional information needed :slight_smile:

Hello,

I am following this tutorial, I ran into the error:

[webpack-cli] Error: Unable to use specified module loaders for “.ts”.
at Object.exports.prepare (/Users/myusername/local-files/quick-code/myfoldernameh/api/node_modules/rechoir/index.js:58:11)

Here is my config file:
const webpack = require(“webpack”);
const path = require(“path”);
const nodeExternals = require(“webpack-node-externals”);

module.exports = {
entry: [“webpack/hot/poll?100”, “./src/index.ts”],
watch: true,
target: “node”,
externals: [
nodeExternals({
allowlist: [“webpack/hot/poll?100”]
})
],
module: {
rules: [
{
test: /.tsx?$/,
use: “ts-loader”,
exclude: /node_modules/
}
]
},
mode: “development”,
resolve: {
extensions: [“.tsx”, “.ts”, “.js”]
},
plugins: [new webpack.HotModuleReplacementPlugin()],
output: {
path: path.join(__dirname, “dist”),
filename: “index.js”
}
};

1 Like

I got some help. Made the webpack config a js file not ts, and updated the package json accordingly, but ultimately it was an extra backtick I had added to the config by accident.

2 Likes

Hello, Jenna. Welcome to the Auth0 Community. I am glad that you got the issue sorted out. Let us know if you have any questions in the future :+1: Thank you for reading the tutorial.

1 Like

Howdy, Adam. Thank for the feedback and for joining the Auth0 Community.

What happens if you open this page directly after you log in: https://dashboard.whatabyte.app/user-profile

Do you see any information? This is the page that the “user tab” opens.

Hi Dan,
I followed this tutorial and ended up with the following error:

> express-ts-api@1.0.0 webpack /home/thomas/Documents/Informatique/WebDev/Express/express-ts-api
> webpack --config webpack.config.ts

[webpack-cli] Error: Unable to use specified module loaders for ".ts".
    at Object.exports.prepare (/home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/rechoir/index.js:58:11)
    at requireConfig (/home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/webpack-cli/lib/groups/ConfigGroup.js:70:17)
    at /home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/webpack-cli/lib/groups/ConfigGroup.js:99:36
    at Array.map (<anonymous>)
    at resolveConfigFiles (/home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/webpack-cli/lib/groups/ConfigGroup.js:89:41)
    at module.exports (/home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/webpack-cli/lib/groups/ConfigGroup.js:233:11)
    at WebpackCLI._baseResolver (/home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/webpack-cli/lib/webpack-cli.js:68:38)
    at /home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/webpack-cli/lib/webpack-cli.js:198:30
    at async WebpackCLI.runOptionGroups (/home/thomas/Documents/Informatique/WebDev/Express/express-ts-api/node_modules/webpack-cli/lib/webpack-cli.js:197:9) {
  failures: [
    { moduleName: 'ts-node/register', module: null, error: [Error] },
    {
      moduleName: 'typescript-node/register',
      module: null,
      error: [Error]
    },
    { moduleName: 'typescript-register', module: null, error: [Error] },
    { moduleName: 'typescript-require', module: null, error: [Error] },
    { moduleName: 'sucrase/register/ts', module: null, error: [Error] },
    { moduleName: '@babel/register', module: null, error: [Error] }
  ]
}

Thanks for your help!

Howdy, Thomas. Thank you for reading the blog post.

What are the dependencies versions of your package.json, please?

1 Like