├── .circleci └── config.yml ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── Bug Report.yml │ ├── Feature Request.yml │ └── config.yml ├── dependabot.yml ├── stale.yml └── workflows │ └── semgrep.yml ├── .gitignore ├── 01-Authorization-RS256 ├── .dockerignore ├── .env.example ├── .gitignore ├── Dockerfile ├── README.md ├── exec.ps1 ├── exec.sh ├── package-lock.json ├── package.json └── server.js ├── 02-Authorization-HS256 ├── .dockerignore ├── .env.example ├── .gitignore ├── Dockerfile ├── README.md ├── exec.ps1 ├── exec.sh ├── package-lock.json ├── package.json └── server.js ├── LICENSE └── README.md /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Common Logic 2 | machine: &machine-cfg 3 | image: ubuntu-2004:202107-02 4 | 5 | defaults: &defaults 6 | steps: 7 | - attach_workspace: 8 | at: ~/ 9 | - run: 10 | name: Prepare environment variables 11 | command: | 12 | cd $AUTH0_CFG 13 | mv .env.example .env 14 | sed -i 's|{DOMAIN}|'$auth0_domain'|g' .env 15 | if [[ $AUTH0_CFG = *"RS256"* ]]; 16 | then 17 | sed -i 's|{API_IDENTIFIER}|'$api_identifier'|g' .env 18 | else 19 | sed -i 's|{API_IDENTIFIER}|'$api_identifier_hs256'|g' .env 20 | sed -i 's|{CLIENT_SECRET}|'$api_signing_secret'|g' .env 21 | fi 22 | - run: 23 | name: Background Server 24 | command: cd $AUTH0_CFG && sh exec.sh 25 | background: true 26 | - run: 27 | name: Wait until server is online 28 | command: | 29 | until $(curl --silent --head --output /dev/null --fail http://localhost:3010/api/public); do 30 | sleep 5 31 | done 32 | - run: 33 | name: Prepare tests 34 | command: | 35 | cd test 36 | echo "AUTH0_DOMAIN=$auth0_domain" >> .env 37 | if [[ $AUTH0_CFG = *"RS256"* ]]; 38 | then 39 | echo "API_IDENTIFIER=$api_identifier" >> .env 40 | else 41 | echo "API_IDENTIFIER=$api_identifier_hs256" >> .env 42 | fi 43 | echo "AUTH0_CLIENT_ID_1=$client_id_scopes_none" >> .env 44 | echo "AUTH0_CLIENT_SECRET_1=$client_secret_scopes_none" >> .env 45 | echo "AUTH0_CLIENT_ID_2=$client_id_scopes_read" >> .env 46 | echo "AUTH0_CLIENT_SECRET_2=$client_secret_scopes_read" >> .env 47 | echo "AUTH0_CLIENT_ID_3=$client_id_scopes_write" >> .env 48 | echo "AUTH0_CLIENT_SECRET_3=$client_secret_scopes_write" >> .env 49 | echo "AUTH0_CLIENT_ID_4=$client_id_scopes_readwrite" >> .env 50 | echo "AUTH0_CLIENT_SECRET_4=$client_secret_scopes_readwrite" >> .env 51 | echo "API_URL=http://localhost:3010" >> .env 52 | npm install 53 | - run: 54 | name: Execute automated tests 55 | command: cd test && npm test 56 | # Jobs and Workflows 57 | version: 2 58 | jobs: 59 | checkout: 60 | machine: 61 | <<: *machine-cfg 62 | steps: 63 | - checkout 64 | - run: 65 | name: Clone test script 66 | command: git clone -b v0.0.1 --depth 1 https://github.com/auth0-samples/api-quickstarts-tests test 67 | - persist_to_workspace: 68 | root: ~/ 69 | paths: 70 | - project 71 | - test 72 | 01-Authorization-RS256: 73 | machine: 74 | <<: *machine-cfg 75 | environment: 76 | AUTH0_CFG: 01-Authorization-RS256 77 | SAMPLE_PATH: 01-Authorization-RS256 78 | <<: *defaults 79 | 02-Authorization-HS256: 80 | machine: 81 | <<: *machine-cfg 82 | environment: 83 | AUTH0_CFG: 02-Authorization-HS256 84 | SAMPLE_PATH: 02-Authorization-HS256 85 | <<: *defaults 86 | 87 | workflows: 88 | version: 2 89 | API-Tests: 90 | jobs: 91 | - checkout: 92 | context: Quickstart API Tests 93 | - 01-Authorization-RS256: 94 | context: Quickstart API Tests 95 | requires: 96 | - checkout 97 | - 02-Authorization-HS256: 98 | context: Quickstart API Tests 99 | requires: 100 | - checkout 101 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @auth0-samples/dx-sdks-engineer 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug Report.yml: -------------------------------------------------------------------------------- 1 | name: 🐞 Report a bug 2 | description: Have you found a bug or issue? Create a bug report for this sample 3 | 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Please do not report security vulnerabilities here**. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues. 9 | 10 | - type: checkboxes 11 | id: checklist 12 | attributes: 13 | label: Checklist 14 | options: 15 | - label: I have looked into the Readme ([RS256](https://github.com/auth0-samples/auth0-express-api-samples/tree/master/01-Authorization-RS256#readme)/[HS256](https://github.com/auth0-samples/auth0-express-api-samples/tree/master/02-Authorization-HS256#readme)) and have not found a suitable solution or answer. 16 | required: true 17 | - label: I have searched the [issues](https://github.com/auth0-samples/auth0-express-api-samples/issues) and have not found a suitable solution or answer. 18 | required: true 19 | - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer. 20 | required: true 21 | - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md). 22 | required: true 23 | 24 | - type: textarea 25 | id: description 26 | attributes: 27 | label: Description 28 | description: Provide a clear and concise description of the issue, including what you expected to happen. 29 | validations: 30 | required: true 31 | 32 | - type: textarea 33 | id: reproduction 34 | attributes: 35 | label: Reproduction 36 | description: Detail the steps taken to reproduce this error, and whether this issue can be reproduced consistently or if it is intermittent. 37 | placeholder: | 38 | 1. Step 1... 39 | 2. Step 2... 40 | 3. ... 41 | validations: 42 | required: true 43 | 44 | - type: textarea 45 | id: additional-context 46 | attributes: 47 | label: Additional context 48 | description: Any other relevant information you think would be useful. 49 | validations: 50 | required: false 51 | 52 | - type: dropdown 53 | id: environment-sample 54 | attributes: 55 | label: Sample 56 | multiple: false 57 | options: 58 | - RS256 59 | - HS256 60 | validations: 61 | required: true 62 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature Request.yml: -------------------------------------------------------------------------------- 1 | name: 🧩 Feature request 2 | description: Suggest an idea or a feature for this sample 3 | labels: ["feature request"] 4 | 5 | body: 6 | - type: checkboxes 7 | id: checklist 8 | attributes: 9 | label: Checklist 10 | options: 11 | - label: I have looked into the Readme ([RS256](https://github.com/auth0-samples/auth0-express-api-samples/tree/master/01-Authorization-RS256#readme)/[HS256](https://github.com/auth0-samples/auth0-express-api-samples/tree/master/02-Authorization-HS256#readme)) and have not found a suitable solution or answer. 12 | required: true 13 | - label: I have searched the [issues](https://github.com/auth0-samples/auth0-express-api-samples/issues) and have not found a suitable solution or answer. 14 | required: true 15 | - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer. 16 | required: true 17 | - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md). 18 | required: true 19 | 20 | - type: textarea 21 | id: description 22 | attributes: 23 | label: Describe the problem you'd like to have solved 24 | description: A clear and concise description of what the problem is. 25 | validations: 26 | required: true 27 | 28 | - type: textarea 29 | id: ideal-solution 30 | attributes: 31 | label: Describe the ideal solution 32 | description: A clear and concise description of what you want to happen. 33 | validations: 34 | required: true 35 | 36 | - type: textarea 37 | id: alternatives-and-workarounds 38 | attributes: 39 | label: Alternatives and current workarounds 40 | description: A clear and concise description of any alternatives you've considered or any workarounds that are currently in place. 41 | validations: 42 | required: false 43 | 44 | - type: textarea 45 | id: additional-context 46 | attributes: 47 | label: Additional context 48 | description: Add any other context or screenshots about the feature request here. 49 | validations: 50 | required: false 51 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 🤔 Help & Questions 4 | url: https://community.auth0.com 5 | about: Ask general support or usage questions in the Auth0 Community forums. 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: "npm" 5 | directory: "/01-Authorization-RS256" 6 | schedule: 7 | interval: "daily" 8 | ignore: 9 | - dependency-name: "*" 10 | update-types: ["version-update:semver-major", "version-update:semver-patch"] 11 | 12 | - package-ecosystem: "npm" 13 | directory: "/02-Authorization-HS256" 14 | schedule: 15 | interval: "daily" 16 | ignore: 17 | - dependency-name: "*" 18 | update-types: ["version-update:semver-major", "version-update:semver-patch"] 19 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | daysUntilClose: 7 8 | 9 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 10 | exemptLabels: [] 11 | 12 | # Set to true to ignore issues with an assignee (defaults to false) 13 | exemptAssignees: true 14 | 15 | # Label to use when marking as stale 16 | staleLabel: closed:stale 17 | 18 | # Comment to post when marking as stale. Set to `false` to disable 19 | markComment: > 20 | This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇‍♂️ -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | name: Semgrep 2 | 3 | on: 4 | pull_request: {} 5 | 6 | push: 7 | branches: ["master", "main"] 8 | 9 | schedule: 10 | - cron: '30 0 1,15 * *' 11 | 12 | jobs: 13 | semgrep: 14 | name: Scan 15 | runs-on: ubuntu-latest 16 | container: 17 | image: returntocorp/semgrep 18 | # Skip any PR created by dependabot to avoid permission issues 19 | if: (github.actor != 'dependabot[bot]') 20 | steps: 21 | - uses: actions/checkout@v3 22 | 23 | - run: semgrep ci 24 | env: 25 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | auth0-variables.ts 4 | .env 5 | npm-debug.log -------------------------------------------------------------------------------- /01-Authorization-RS256/.dockerignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | node_modules 3 | .gitignore 4 | .env.example 5 | exce.sh 6 | exec.ps1 7 | .env 8 | -------------------------------------------------------------------------------- /01-Authorization-RS256/.env.example: -------------------------------------------------------------------------------- 1 | AUDIENCE={API_IDENTIFIER} 2 | ISSUER_BASE_URL=https://{DOMAIN} 3 | -------------------------------------------------------------------------------- /01-Authorization-RS256/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | auth0-variables.ts 4 | .env -------------------------------------------------------------------------------- /01-Authorization-RS256/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | WORKDIR /home/app 4 | 5 | ADD package.json /home/app 6 | RUN npm install 7 | ADD . /home/app 8 | 9 | CMD ["npm", "start"] 10 | 11 | EXPOSE 3010 12 | -------------------------------------------------------------------------------- /01-Authorization-RS256/README.md: -------------------------------------------------------------------------------- 1 | # Express Authorization for RS256-Signed Tokens 2 | 3 | This sample demonstrates how to protect endpoints in an Express API by verifying an incoming JWT access token signed by Auth0. The token must be signed with the RS256 algorithm and must be verified against your Auth0 JSON Web Key Set. 4 | 5 | ## Getting Started 6 | 7 | If you haven't already done so, [sign up](https://auth0.com) for your free Auth0 account and create a new client in the [dashboard](https://manage.auth0.com). 8 | 9 | Clone the repo or download it from the Express API quickstart page in Auth0's documentation. 10 | 11 | ## Setup the `.env` File 12 | 13 | If you download this sample from the Express API quickstart page, a `.env` file will come pre-populated with your API identifier and Auth0 domain. If you clone the repo from GitHub, you will need to rename `.env.example` to `.env` and provide these values manually. 14 | 15 | ## Install the Dependencies and Start the API 16 | 17 | ```bash 18 | npm install 19 | npm start 20 | ``` 21 | 22 | The API will be served at `http://localhost:3010`. 23 | 24 | ## Endpoints 25 | 26 | The sample includes these endpoints: 27 | 28 | **GET** /api/public 29 | * An unprotected endpoint which returns a message on success. Does not require a valid JWT access token. 30 | 31 | **GET** /api/private 32 | * A protected endpoint which returns a message on success. Requires a valid JWT access token with a `scope` of `read:messages`. 33 | 34 | ## Running the Sample With Docker 35 | 36 | In order to run the example with docker you need to have `docker` installed. 37 | 38 | You also need to set the client credentials as explained [previously](#setup-the-env-file). 39 | 40 | Execute in command line `sh exec.sh` to run the Docker in Linux, or `.\exec.ps1` to run the Docker in Windows. 41 | 42 | ## What is Auth0? 43 | 44 | Auth0 helps you to: 45 | 46 | * Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. 47 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. 48 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. 49 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. 50 | * Analytics of how, when and where users are logging in. 51 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). 52 | 53 | ## Create a free Auth0 account 54 | 55 | 1. Go to [Auth0](https://auth0.com/signup) and click Sign Up. 56 | 2. Use Google, GitHub or Microsoft Account to login. 57 | 58 | ## Issue Reporting 59 | 60 | If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. 61 | 62 | ## Author 63 | 64 | [Auth0](https://auth0.com) 65 | 66 | ## License 67 | 68 | This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. 69 | -------------------------------------------------------------------------------- /01-Authorization-RS256/exec.ps1: -------------------------------------------------------------------------------- 1 | docker build -t auth0-express-api-rs256 . 2 | docker run --env-file .env -p 3010:3010 -it auth0-express-api-rs256 3 | -------------------------------------------------------------------------------- /01-Authorization-RS256/exec.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | docker build -t auth0-express-api-rs256 . 3 | docker run --env-file .env -p 3010:3010 -it auth0-express-api-rs256 4 | -------------------------------------------------------------------------------- /01-Authorization-RS256/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "authenticate-rs256", 3 | "version": "0.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.8", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 10 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 11 | "requires": { 12 | "mime-types": "~2.1.34", 13 | "negotiator": "0.6.3" 14 | } 15 | }, 16 | "array-flatten": { 17 | "version": "1.1.1", 18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 19 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 20 | }, 21 | "body-parser": { 22 | "version": "1.20.1", 23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 24 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 25 | "requires": { 26 | "bytes": "3.1.2", 27 | "content-type": "~1.0.4", 28 | "debug": "2.6.9", 29 | "depd": "2.0.0", 30 | "destroy": "1.2.0", 31 | "http-errors": "2.0.0", 32 | "iconv-lite": "0.4.24", 33 | "on-finished": "2.4.1", 34 | "qs": "6.11.0", 35 | "raw-body": "2.5.1", 36 | "type-is": "~1.6.18", 37 | "unpipe": "1.0.0" 38 | } 39 | }, 40 | "bytes": { 41 | "version": "3.1.2", 42 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 43 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 44 | }, 45 | "call-bind": { 46 | "version": "1.0.2", 47 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 48 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 49 | "requires": { 50 | "function-bind": "^1.1.1", 51 | "get-intrinsic": "^1.0.2" 52 | } 53 | }, 54 | "content-disposition": { 55 | "version": "0.5.4", 56 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 57 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 58 | "requires": { 59 | "safe-buffer": "5.2.1" 60 | } 61 | }, 62 | "content-type": { 63 | "version": "1.0.4", 64 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 65 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 66 | }, 67 | "cookie": { 68 | "version": "0.5.0", 69 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 70 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 71 | }, 72 | "cookie-signature": { 73 | "version": "1.0.6", 74 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 75 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 76 | }, 77 | "cors": { 78 | "version": "2.8.5", 79 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 80 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 81 | "requires": { 82 | "object-assign": "^4", 83 | "vary": "^1" 84 | } 85 | }, 86 | "debug": { 87 | "version": "2.6.9", 88 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 89 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 90 | "requires": { 91 | "ms": "2.0.0" 92 | } 93 | }, 94 | "depd": { 95 | "version": "2.0.0", 96 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 97 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 98 | }, 99 | "destroy": { 100 | "version": "1.2.0", 101 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 102 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 103 | }, 104 | "dotenv": { 105 | "version": "10.0.0", 106 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", 107 | "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" 108 | }, 109 | "ee-first": { 110 | "version": "1.1.1", 111 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 112 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 113 | }, 114 | "encodeurl": { 115 | "version": "1.0.2", 116 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 117 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 118 | }, 119 | "escape-html": { 120 | "version": "1.0.3", 121 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 122 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 123 | }, 124 | "etag": { 125 | "version": "1.8.1", 126 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 127 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 128 | }, 129 | "express": { 130 | "version": "4.18.2", 131 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 132 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 133 | "requires": { 134 | "accepts": "~1.3.8", 135 | "array-flatten": "1.1.1", 136 | "body-parser": "1.20.1", 137 | "content-disposition": "0.5.4", 138 | "content-type": "~1.0.4", 139 | "cookie": "0.5.0", 140 | "cookie-signature": "1.0.6", 141 | "debug": "2.6.9", 142 | "depd": "2.0.0", 143 | "encodeurl": "~1.0.2", 144 | "escape-html": "~1.0.3", 145 | "etag": "~1.8.1", 146 | "finalhandler": "1.2.0", 147 | "fresh": "0.5.2", 148 | "http-errors": "2.0.0", 149 | "merge-descriptors": "1.0.1", 150 | "methods": "~1.1.2", 151 | "on-finished": "2.4.1", 152 | "parseurl": "~1.3.3", 153 | "path-to-regexp": "0.1.7", 154 | "proxy-addr": "~2.0.7", 155 | "qs": "6.11.0", 156 | "range-parser": "~1.2.1", 157 | "safe-buffer": "5.2.1", 158 | "send": "0.18.0", 159 | "serve-static": "1.15.0", 160 | "setprototypeof": "1.2.0", 161 | "statuses": "2.0.1", 162 | "type-is": "~1.6.18", 163 | "utils-merge": "1.0.1", 164 | "vary": "~1.1.2" 165 | } 166 | }, 167 | "express-oauth2-jwt-bearer": { 168 | "version": "1.6.0", 169 | "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.6.0.tgz", 170 | "integrity": "sha512-HXnez7vocYlOqlfF3ozPcf/WE3zxT7zfUNfeg5FHJnvNwhBYlNXiPOvuCtBalis8xcigvwtInzEKhBuH87+9ug==", 171 | "requires": { 172 | "jose": "^4.13.1" 173 | } 174 | }, 175 | "finalhandler": { 176 | "version": "1.2.0", 177 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 178 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 179 | "requires": { 180 | "debug": "2.6.9", 181 | "encodeurl": "~1.0.2", 182 | "escape-html": "~1.0.3", 183 | "on-finished": "2.4.1", 184 | "parseurl": "~1.3.3", 185 | "statuses": "2.0.1", 186 | "unpipe": "~1.0.0" 187 | } 188 | }, 189 | "forwarded": { 190 | "version": "0.2.0", 191 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 192 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 193 | }, 194 | "fresh": { 195 | "version": "0.5.2", 196 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 197 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 198 | }, 199 | "function-bind": { 200 | "version": "1.1.1", 201 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 202 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 203 | }, 204 | "get-intrinsic": { 205 | "version": "1.1.3", 206 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 207 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 208 | "requires": { 209 | "function-bind": "^1.1.1", 210 | "has": "^1.0.3", 211 | "has-symbols": "^1.0.3" 212 | } 213 | }, 214 | "has": { 215 | "version": "1.0.3", 216 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 217 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 218 | "requires": { 219 | "function-bind": "^1.1.1" 220 | } 221 | }, 222 | "has-symbols": { 223 | "version": "1.0.3", 224 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 225 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 226 | }, 227 | "http-errors": { 228 | "version": "2.0.0", 229 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 230 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 231 | "requires": { 232 | "depd": "2.0.0", 233 | "inherits": "2.0.4", 234 | "setprototypeof": "1.2.0", 235 | "statuses": "2.0.1", 236 | "toidentifier": "1.0.1" 237 | } 238 | }, 239 | "iconv-lite": { 240 | "version": "0.4.24", 241 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 242 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 243 | "requires": { 244 | "safer-buffer": ">= 2.1.2 < 3" 245 | } 246 | }, 247 | "inherits": { 248 | "version": "2.0.4", 249 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 250 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 251 | }, 252 | "ipaddr.js": { 253 | "version": "1.9.1", 254 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 255 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 256 | }, 257 | "jose": { 258 | "version": "4.15.2", 259 | "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.2.tgz", 260 | "integrity": "sha512-IY73F228OXRl9ar3jJagh7Vnuhj/GzBunPiZP13K0lOl7Am9SoWW3kEzq3MCllJMTtZqHTiDXQvoRd4U95aU6A==" 261 | }, 262 | "media-typer": { 263 | "version": "0.3.0", 264 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 265 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 266 | }, 267 | "merge-descriptors": { 268 | "version": "1.0.1", 269 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 270 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 271 | }, 272 | "methods": { 273 | "version": "1.1.2", 274 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 275 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 276 | }, 277 | "mime": { 278 | "version": "1.6.0", 279 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 280 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 281 | }, 282 | "mime-db": { 283 | "version": "1.52.0", 284 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 285 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 286 | }, 287 | "mime-types": { 288 | "version": "2.1.35", 289 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 290 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 291 | "requires": { 292 | "mime-db": "1.52.0" 293 | } 294 | }, 295 | "ms": { 296 | "version": "2.0.0", 297 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 298 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 299 | }, 300 | "negotiator": { 301 | "version": "0.6.3", 302 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 303 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 304 | }, 305 | "object-assign": { 306 | "version": "4.1.1", 307 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 308 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 309 | }, 310 | "object-inspect": { 311 | "version": "1.12.2", 312 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 313 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" 314 | }, 315 | "on-finished": { 316 | "version": "2.4.1", 317 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 318 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 319 | "requires": { 320 | "ee-first": "1.1.1" 321 | } 322 | }, 323 | "parseurl": { 324 | "version": "1.3.3", 325 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 326 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 327 | }, 328 | "path-to-regexp": { 329 | "version": "0.1.7", 330 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 331 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 332 | }, 333 | "proxy-addr": { 334 | "version": "2.0.7", 335 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 336 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 337 | "requires": { 338 | "forwarded": "0.2.0", 339 | "ipaddr.js": "1.9.1" 340 | } 341 | }, 342 | "qs": { 343 | "version": "6.11.0", 344 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 345 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 346 | "requires": { 347 | "side-channel": "^1.0.4" 348 | } 349 | }, 350 | "range-parser": { 351 | "version": "1.2.1", 352 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 353 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 354 | }, 355 | "raw-body": { 356 | "version": "2.5.1", 357 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 358 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 359 | "requires": { 360 | "bytes": "3.1.2", 361 | "http-errors": "2.0.0", 362 | "iconv-lite": "0.4.24", 363 | "unpipe": "1.0.0" 364 | } 365 | }, 366 | "safe-buffer": { 367 | "version": "5.2.1", 368 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 369 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 370 | }, 371 | "safer-buffer": { 372 | "version": "2.1.2", 373 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 374 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 375 | }, 376 | "send": { 377 | "version": "0.18.0", 378 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 379 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 380 | "requires": { 381 | "debug": "2.6.9", 382 | "depd": "2.0.0", 383 | "destroy": "1.2.0", 384 | "encodeurl": "~1.0.2", 385 | "escape-html": "~1.0.3", 386 | "etag": "~1.8.1", 387 | "fresh": "0.5.2", 388 | "http-errors": "2.0.0", 389 | "mime": "1.6.0", 390 | "ms": "2.1.3", 391 | "on-finished": "2.4.1", 392 | "range-parser": "~1.2.1", 393 | "statuses": "2.0.1" 394 | }, 395 | "dependencies": { 396 | "ms": { 397 | "version": "2.1.3", 398 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 399 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 400 | } 401 | } 402 | }, 403 | "serve-static": { 404 | "version": "1.15.0", 405 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 406 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 407 | "requires": { 408 | "encodeurl": "~1.0.2", 409 | "escape-html": "~1.0.3", 410 | "parseurl": "~1.3.3", 411 | "send": "0.18.0" 412 | } 413 | }, 414 | "setprototypeof": { 415 | "version": "1.2.0", 416 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 417 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 418 | }, 419 | "side-channel": { 420 | "version": "1.0.4", 421 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 422 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 423 | "requires": { 424 | "call-bind": "^1.0.0", 425 | "get-intrinsic": "^1.0.2", 426 | "object-inspect": "^1.9.0" 427 | } 428 | }, 429 | "statuses": { 430 | "version": "2.0.1", 431 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 432 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 433 | }, 434 | "toidentifier": { 435 | "version": "1.0.1", 436 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 437 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 438 | }, 439 | "type-is": { 440 | "version": "1.6.18", 441 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 442 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 443 | "requires": { 444 | "media-typer": "0.3.0", 445 | "mime-types": "~2.1.24" 446 | } 447 | }, 448 | "unpipe": { 449 | "version": "1.0.0", 450 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 451 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 452 | }, 453 | "utils-merge": { 454 | "version": "1.0.1", 455 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 456 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 457 | }, 458 | "vary": { 459 | "version": "1.1.2", 460 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 461 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 462 | } 463 | } 464 | } 465 | -------------------------------------------------------------------------------- /01-Authorization-RS256/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "authenticate-rs256", 3 | "version": "0.0.0", 4 | "description": "Sample demonstrating how to verify a JWT signed with RS256", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "dev": "nodemon server.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/auth0-samples/auth0-express-api-samples.git" 13 | }, 14 | "author": "Auth0", 15 | "license": "MIT", 16 | "dependencies": { 17 | "cors": "^2.8.5", 18 | "dotenv": "^10.0.0", 19 | "express": "^4.18.2", 20 | "express-oauth2-jwt-bearer": "^1.6.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /01-Authorization-RS256/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const { auth, requiredScopes } = require('express-oauth2-jwt-bearer'); 4 | const cors = require('cors'); 5 | require('dotenv').config(); 6 | 7 | if (!process.env.ISSUER_BASE_URL || !process.env.AUDIENCE) { 8 | throw 'Make sure you have ISSUER_BASE_URL, and AUDIENCE in your .env file'; 9 | } 10 | 11 | const corsOptions = { 12 | origin: 'http://localhost:3000' 13 | }; 14 | 15 | app.use(cors(corsOptions)); 16 | 17 | const checkJwt = auth(); 18 | 19 | app.get('/api/public', function(req, res) { 20 | res.json({ 21 | message: 'Hello from a public endpoint! You don\'t need to be authenticated to see this.' 22 | }); 23 | }); 24 | 25 | app.get('/api/private', checkJwt, function(req, res) { 26 | res.json({ 27 | message: 'Hello from a private endpoint! You need to be authenticated to see this.' 28 | }); 29 | }); 30 | 31 | app.get('/api/private-scoped', checkJwt, requiredScopes('read:messages'), function(req, res) { 32 | res.json({ 33 | message: 'Hello from a private endpoint! You need to be authenticated and have a scope of read:messages to see this.' 34 | }); 35 | }); 36 | 37 | app.use(function(err, req, res, next){ 38 | console.error(err.stack); 39 | return res.set(err.headers).status(err.status).json({ message: err.message }); 40 | }); 41 | 42 | app.listen(3010); 43 | console.log('Listening on http://localhost:3010'); 44 | -------------------------------------------------------------------------------- /02-Authorization-HS256/.dockerignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | node_modules 3 | .gitignore 4 | .env.example 5 | exce.sh 6 | exec.ps1 7 | .env 8 | -------------------------------------------------------------------------------- /02-Authorization-HS256/.env.example: -------------------------------------------------------------------------------- 1 | ISSUER=https://{DOMAIN}/ 2 | AUDIENCE={API_IDENTIFIER} 3 | SECRET={CLIENT_SECRET} 4 | -------------------------------------------------------------------------------- /02-Authorization-HS256/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | auth0-variables.ts 4 | .env -------------------------------------------------------------------------------- /02-Authorization-HS256/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | WORKDIR /home/app 4 | 5 | ADD package.json /home/app 6 | RUN npm install 7 | ADD . /home/app 8 | 9 | CMD ["npm", "start"] 10 | 11 | EXPOSE 3010 12 | -------------------------------------------------------------------------------- /02-Authorization-HS256/README.md: -------------------------------------------------------------------------------- 1 | # Express Authorization for HS256-Signed Tokens 2 | 3 | This sample demonstrates how to protect endpoints in an Express API by verifying an incoming JWT signed by Auth0. The token must be signed with the HS256 algorithm and must be verified against the signing secret. 4 | 5 | ## Getting Started 6 | 7 | If you haven't already done so, [sign up](https://auth0.com) for your free Auth0 account and create a new client in the [dashboard](https://manage.auth0.com). 8 | 9 | Clone the repo or download it from the Express API quickstart page in Auth0's documentation. 10 | 11 | ## Setup the `.env` File 12 | 13 | If you download this sample from the Express API quickstart page, a `.env` file will come pre-populated with your API identifier and Auth0 domain. If you clone the repo from GitHub, you will need to rename `.env.example` to `.env` and provide these values manually. 14 | 15 | ## Install the Dependencies and Start the API 16 | 17 | ```bash 18 | npm install 19 | npm start 20 | ``` 21 | 22 | The API will be served at `http://localhost:3010`. 23 | 24 | ## Endpoints 25 | 26 | The sample includes these endpoints: 27 | 28 | **GET** /api/public 29 | * An unprotected endpoint which returns a message on success. Does not require a valid JWT access token. 30 | 31 | **GET** /api/private 32 | * A protected endpoint which returns a message on success. Requires a valid JWT access token. A protected endpoint which returns a message on success. Requires a valid JWT access token with a `scope` of `read:messages`. 33 | 34 | ## Running the Sample With Docker 35 | 36 | In order to run the example with docker you need to have `docker` installed. 37 | 38 | You also need to set the client credentials as explained [previously](#setup-the-env-file). 39 | 40 | Execute in command line `sh exec.sh` to run the Docker in Linux, or `.\exec.ps1` to run the Docker in Windows. 41 | 42 | ## What is Auth0? 43 | 44 | Auth0 helps you to: 45 | 46 | * Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. 47 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. 48 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. 49 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. 50 | * Analytics of how, when and where users are logging in. 51 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). 52 | 53 | ## Create a free Auth0 account 54 | 55 | 1. Go to [Auth0](https://auth0.com/signup) and click Sign Up. 56 | 2. Use Google, GitHub or Microsoft Account to login. 57 | 58 | ## Issue Reporting 59 | 60 | If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. 61 | 62 | ## Author 63 | 64 | [Auth0](https://auth0.com) 65 | 66 | ## License 67 | 68 | This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. 69 | -------------------------------------------------------------------------------- /02-Authorization-HS256/exec.ps1: -------------------------------------------------------------------------------- 1 | docker build -t auth0-express-api-rs256 . 2 | docker run --env-file .env -p 3010:3010 -it auth0-express-api-rs256 3 | -------------------------------------------------------------------------------- /02-Authorization-HS256/exec.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | docker build -t auth0-express-api-hs256 . 3 | docker run --env-file .env -p 3010:3010 -it auth0-express-api-hs256 4 | -------------------------------------------------------------------------------- /02-Authorization-HS256/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "authenticate-rs256", 3 | "version": "0.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.8", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 10 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 11 | "requires": { 12 | "mime-types": "~2.1.34", 13 | "negotiator": "0.6.3" 14 | } 15 | }, 16 | "array-flatten": { 17 | "version": "1.1.1", 18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 19 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 20 | }, 21 | "body-parser": { 22 | "version": "1.20.1", 23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 24 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 25 | "requires": { 26 | "bytes": "3.1.2", 27 | "content-type": "~1.0.4", 28 | "debug": "2.6.9", 29 | "depd": "2.0.0", 30 | "destroy": "1.2.0", 31 | "http-errors": "2.0.0", 32 | "iconv-lite": "0.4.24", 33 | "on-finished": "2.4.1", 34 | "qs": "6.11.0", 35 | "raw-body": "2.5.1", 36 | "type-is": "~1.6.18", 37 | "unpipe": "1.0.0" 38 | } 39 | }, 40 | "bytes": { 41 | "version": "3.1.2", 42 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 43 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 44 | }, 45 | "call-bind": { 46 | "version": "1.0.2", 47 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 48 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 49 | "requires": { 50 | "function-bind": "^1.1.1", 51 | "get-intrinsic": "^1.0.2" 52 | } 53 | }, 54 | "content-disposition": { 55 | "version": "0.5.4", 56 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 57 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 58 | "requires": { 59 | "safe-buffer": "5.2.1" 60 | } 61 | }, 62 | "content-type": { 63 | "version": "1.0.4", 64 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 65 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 66 | }, 67 | "cookie": { 68 | "version": "0.5.0", 69 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 70 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 71 | }, 72 | "cookie-signature": { 73 | "version": "1.0.6", 74 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 75 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 76 | }, 77 | "cors": { 78 | "version": "2.8.5", 79 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 80 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 81 | "requires": { 82 | "object-assign": "^4", 83 | "vary": "^1" 84 | } 85 | }, 86 | "debug": { 87 | "version": "2.6.9", 88 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 89 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 90 | "requires": { 91 | "ms": "2.0.0" 92 | } 93 | }, 94 | "depd": { 95 | "version": "2.0.0", 96 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 97 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 98 | }, 99 | "destroy": { 100 | "version": "1.2.0", 101 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 102 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 103 | }, 104 | "dotenv": { 105 | "version": "10.0.0", 106 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", 107 | "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" 108 | }, 109 | "ee-first": { 110 | "version": "1.1.1", 111 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 112 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 113 | }, 114 | "encodeurl": { 115 | "version": "1.0.2", 116 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 117 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 118 | }, 119 | "escape-html": { 120 | "version": "1.0.3", 121 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 122 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 123 | }, 124 | "etag": { 125 | "version": "1.8.1", 126 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 127 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 128 | }, 129 | "express": { 130 | "version": "4.18.2", 131 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 132 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 133 | "requires": { 134 | "accepts": "~1.3.8", 135 | "array-flatten": "1.1.1", 136 | "body-parser": "1.20.1", 137 | "content-disposition": "0.5.4", 138 | "content-type": "~1.0.4", 139 | "cookie": "0.5.0", 140 | "cookie-signature": "1.0.6", 141 | "debug": "2.6.9", 142 | "depd": "2.0.0", 143 | "encodeurl": "~1.0.2", 144 | "escape-html": "~1.0.3", 145 | "etag": "~1.8.1", 146 | "finalhandler": "1.2.0", 147 | "fresh": "0.5.2", 148 | "http-errors": "2.0.0", 149 | "merge-descriptors": "1.0.1", 150 | "methods": "~1.1.2", 151 | "on-finished": "2.4.1", 152 | "parseurl": "~1.3.3", 153 | "path-to-regexp": "0.1.7", 154 | "proxy-addr": "~2.0.7", 155 | "qs": "6.11.0", 156 | "range-parser": "~1.2.1", 157 | "safe-buffer": "5.2.1", 158 | "send": "0.18.0", 159 | "serve-static": "1.15.0", 160 | "setprototypeof": "1.2.0", 161 | "statuses": "2.0.1", 162 | "type-is": "~1.6.18", 163 | "utils-merge": "1.0.1", 164 | "vary": "~1.1.2" 165 | } 166 | }, 167 | "express-oauth2-jwt-bearer": { 168 | "version": "1.6.0", 169 | "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.6.0.tgz", 170 | "integrity": "sha512-HXnez7vocYlOqlfF3ozPcf/WE3zxT7zfUNfeg5FHJnvNwhBYlNXiPOvuCtBalis8xcigvwtInzEKhBuH87+9ug==", 171 | "requires": { 172 | "jose": "^4.13.1" 173 | } 174 | }, 175 | "finalhandler": { 176 | "version": "1.2.0", 177 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 178 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 179 | "requires": { 180 | "debug": "2.6.9", 181 | "encodeurl": "~1.0.2", 182 | "escape-html": "~1.0.3", 183 | "on-finished": "2.4.1", 184 | "parseurl": "~1.3.3", 185 | "statuses": "2.0.1", 186 | "unpipe": "~1.0.0" 187 | } 188 | }, 189 | "forwarded": { 190 | "version": "0.2.0", 191 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 192 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 193 | }, 194 | "fresh": { 195 | "version": "0.5.2", 196 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 197 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 198 | }, 199 | "function-bind": { 200 | "version": "1.1.1", 201 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 202 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 203 | }, 204 | "get-intrinsic": { 205 | "version": "1.1.3", 206 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 207 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 208 | "requires": { 209 | "function-bind": "^1.1.1", 210 | "has": "^1.0.3", 211 | "has-symbols": "^1.0.3" 212 | } 213 | }, 214 | "has": { 215 | "version": "1.0.3", 216 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 217 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 218 | "requires": { 219 | "function-bind": "^1.1.1" 220 | } 221 | }, 222 | "has-symbols": { 223 | "version": "1.0.3", 224 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 225 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 226 | }, 227 | "http-errors": { 228 | "version": "2.0.0", 229 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 230 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 231 | "requires": { 232 | "depd": "2.0.0", 233 | "inherits": "2.0.4", 234 | "setprototypeof": "1.2.0", 235 | "statuses": "2.0.1", 236 | "toidentifier": "1.0.1" 237 | } 238 | }, 239 | "iconv-lite": { 240 | "version": "0.4.24", 241 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 242 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 243 | "requires": { 244 | "safer-buffer": ">= 2.1.2 < 3" 245 | } 246 | }, 247 | "inherits": { 248 | "version": "2.0.4", 249 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 250 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 251 | }, 252 | "ipaddr.js": { 253 | "version": "1.9.1", 254 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 255 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 256 | }, 257 | "jose": { 258 | "version": "4.15.2", 259 | "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.2.tgz", 260 | "integrity": "sha512-IY73F228OXRl9ar3jJagh7Vnuhj/GzBunPiZP13K0lOl7Am9SoWW3kEzq3MCllJMTtZqHTiDXQvoRd4U95aU6A==" 261 | }, 262 | "media-typer": { 263 | "version": "0.3.0", 264 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 265 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 266 | }, 267 | "merge-descriptors": { 268 | "version": "1.0.1", 269 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 270 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 271 | }, 272 | "methods": { 273 | "version": "1.1.2", 274 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 275 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 276 | }, 277 | "mime": { 278 | "version": "1.6.0", 279 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 280 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 281 | }, 282 | "mime-db": { 283 | "version": "1.52.0", 284 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 285 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 286 | }, 287 | "mime-types": { 288 | "version": "2.1.35", 289 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 290 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 291 | "requires": { 292 | "mime-db": "1.52.0" 293 | } 294 | }, 295 | "ms": { 296 | "version": "2.0.0", 297 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 298 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 299 | }, 300 | "negotiator": { 301 | "version": "0.6.3", 302 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 303 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 304 | }, 305 | "object-assign": { 306 | "version": "4.1.1", 307 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 308 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 309 | }, 310 | "object-inspect": { 311 | "version": "1.12.2", 312 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 313 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" 314 | }, 315 | "on-finished": { 316 | "version": "2.4.1", 317 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 318 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 319 | "requires": { 320 | "ee-first": "1.1.1" 321 | } 322 | }, 323 | "parseurl": { 324 | "version": "1.3.3", 325 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 326 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 327 | }, 328 | "path-to-regexp": { 329 | "version": "0.1.7", 330 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 331 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 332 | }, 333 | "proxy-addr": { 334 | "version": "2.0.7", 335 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 336 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 337 | "requires": { 338 | "forwarded": "0.2.0", 339 | "ipaddr.js": "1.9.1" 340 | } 341 | }, 342 | "qs": { 343 | "version": "6.11.0", 344 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 345 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 346 | "requires": { 347 | "side-channel": "^1.0.4" 348 | } 349 | }, 350 | "range-parser": { 351 | "version": "1.2.1", 352 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 353 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 354 | }, 355 | "raw-body": { 356 | "version": "2.5.1", 357 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 358 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 359 | "requires": { 360 | "bytes": "3.1.2", 361 | "http-errors": "2.0.0", 362 | "iconv-lite": "0.4.24", 363 | "unpipe": "1.0.0" 364 | } 365 | }, 366 | "safe-buffer": { 367 | "version": "5.2.1", 368 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 369 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 370 | }, 371 | "safer-buffer": { 372 | "version": "2.1.2", 373 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 374 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 375 | }, 376 | "send": { 377 | "version": "0.18.0", 378 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 379 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 380 | "requires": { 381 | "debug": "2.6.9", 382 | "depd": "2.0.0", 383 | "destroy": "1.2.0", 384 | "encodeurl": "~1.0.2", 385 | "escape-html": "~1.0.3", 386 | "etag": "~1.8.1", 387 | "fresh": "0.5.2", 388 | "http-errors": "2.0.0", 389 | "mime": "1.6.0", 390 | "ms": "2.1.3", 391 | "on-finished": "2.4.1", 392 | "range-parser": "~1.2.1", 393 | "statuses": "2.0.1" 394 | }, 395 | "dependencies": { 396 | "ms": { 397 | "version": "2.1.3", 398 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 399 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 400 | } 401 | } 402 | }, 403 | "serve-static": { 404 | "version": "1.15.0", 405 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 406 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 407 | "requires": { 408 | "encodeurl": "~1.0.2", 409 | "escape-html": "~1.0.3", 410 | "parseurl": "~1.3.3", 411 | "send": "0.18.0" 412 | } 413 | }, 414 | "setprototypeof": { 415 | "version": "1.2.0", 416 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 417 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 418 | }, 419 | "side-channel": { 420 | "version": "1.0.4", 421 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 422 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 423 | "requires": { 424 | "call-bind": "^1.0.0", 425 | "get-intrinsic": "^1.0.2", 426 | "object-inspect": "^1.9.0" 427 | } 428 | }, 429 | "statuses": { 430 | "version": "2.0.1", 431 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 432 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 433 | }, 434 | "toidentifier": { 435 | "version": "1.0.1", 436 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 437 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 438 | }, 439 | "type-is": { 440 | "version": "1.6.18", 441 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 442 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 443 | "requires": { 444 | "media-typer": "0.3.0", 445 | "mime-types": "~2.1.24" 446 | } 447 | }, 448 | "unpipe": { 449 | "version": "1.0.0", 450 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 451 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 452 | }, 453 | "utils-merge": { 454 | "version": "1.0.1", 455 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 456 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 457 | }, 458 | "vary": { 459 | "version": "1.1.2", 460 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 461 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 462 | } 463 | } 464 | } 465 | -------------------------------------------------------------------------------- /02-Authorization-HS256/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "authenticate-rs256", 3 | "version": "0.0.0", 4 | "description": "Sample demonstrating how to verify a JWT signed with RS256", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "dev": "nodemon server.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/auth0-samples/auth0-express-api-samples.git" 13 | }, 14 | "author": "Auth0", 15 | "license": "MIT", 16 | "dependencies": { 17 | "cors": "^2.8.5", 18 | "dotenv": "^10.0.0", 19 | "express": "^4.18.2", 20 | "express-oauth2-jwt-bearer": "^1.6.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /02-Authorization-HS256/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const { auth, requiredScopes } = require('express-oauth2-jwt-bearer'); 4 | const cors = require('cors'); 5 | require('dotenv').config(); 6 | 7 | if (!process.env.ISSUER || !process.env.AUDIENCE || !process.env.SECRET) { 8 | throw 'Make sure you have ISSUER, AUDIENCE and SECRET in your .env file'; 9 | } 10 | 11 | const corsOptions = { 12 | origin: 'http://localhost:3000' 13 | }; 14 | 15 | app.use(cors(corsOptions)); 16 | 17 | const checkJwt = auth({ 18 | tokenSigningAlg: 'HS256' 19 | }); 20 | 21 | app.get('/api/public', function(req, res) { 22 | res.json({ 23 | message: 'Hello from a public endpoint! You don\'t need to be authenticated to see this.' 24 | }); 25 | }); 26 | 27 | app.get('/api/private', checkJwt, function(req, res) { 28 | res.json({ 29 | message: 'Hello from a private endpoint! You need to be authenticated to see this.' 30 | }); 31 | }); 32 | 33 | app.get('/api/private-scoped', checkJwt, requiredScopes('read:messages'), function(req, res) { 34 | res.json({ 35 | message: 'Hello from a private endpoint! You need to be authenticated and have a scope of read:messages to see this.' 36 | }); 37 | }); 38 | 39 | app.use(function(err, req, res, next){ 40 | console.error(err.stack); 41 | return res.set(err.headers).status(err.status).json({ message: err.message }); 42 | }); 43 | 44 | app.listen(3010); 45 | console.log('Listening on http://localhost:3010'); 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Auth0 Samples 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Auth0 Express API Samples 2 | 3 | [![CircleCI](https://img.shields.io/circleci/project/github/auth0-samples/auth0-express-api-samples.svg?style=flat-square)](https://circleci.com/gh/auth0-samples/auth0-express-api-samples/tree/master) 4 | 5 | These samples demonstrate how to create an API with Express which only permits access to resources if a valid **access token** is included. This verification is done by validating the signature and claims in a JSON Web Token (JWT) signed by Auth0. 6 | 7 | These samples do not demonstrate how to sign a JWT but rather assume that a user has already been authenticated by Auth0 and holds an access token for API access. For information on how to use Auth0 to authenticate users, see [the docs](https://auth0.com/docs). 8 | 9 | ## What is Auth0? 10 | 11 | Auth0 helps you to: 12 | 13 | * Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. 14 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. 15 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. 16 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. 17 | * Analytics of how, when and where users are logging in. 18 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). 19 | 20 | ## Create a free Auth0 account 21 | 22 | 1. Go to [Auth0](https://auth0.com/signup) and click Sign Up. 23 | 2. Use Google, GitHub or Microsoft Account to login. 24 | 25 | ## Issue Reporting 26 | 27 | If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. 28 | 29 | ## Author 30 | 31 | [Auth0](auth0.com) 32 | 33 | ## License 34 | 35 | This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. 36 | --------------------------------------------------------------------------------