/nestjs-oauth2-example

OAuth2 implementation example using NestJs

Primary LanguageTypeScriptMIT LicenseMIT

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications.

NPM Version Package License NPM Downloads CircleCI Coverage Discord Backers on Open Collective Sponsors on Open Collective Support us

Description

Nest framework TypeScript starter repository.

Installation

$ npm install

Running the app

# development
$ npm run start

# watch mode
$ npm run start:dev

# production mode
$ npm run start:prod

Test

# unit tests
$ npm run test

# e2e tests
$ npm run test:e2e

# test coverage
$ npm run test:cov

Support

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.

Stay in touch

License

Nest is MIT licensed.

How to test this server's authorization_code flow

  • Create an .env file at the root of your repo (near package.json) with content exactly as in .env.example. SECURE_KEY can be generated by command

    $ npm run gen:secure-key
  • update username and password for your local mysql database in ormconfig.json

  • run

    $ npm run start:dev

    this will create necessary tables in database for you as well as start the application

  • Add client metadata that will be used to access our oidc provider by insert to client table the following content

      INSERT INTO `oauth`.`client`
      (`id`,
      `data`)
      VALUES
      ('foo',
      '{"client_id":"foo","client_secret":"foobar","redirect_uris":["https://jwt.io"],"response_types":["code"],"grant_types":["authorization_code"],"token_endpoint_auth_method\":"client_secret_basic"}');

    this will create a client with client_id=foo and client_secret=foobar

  • register a user by POST request (using POSTMAN or curl to the following endpoint)

    curl --location --request POST 'localhost:3000/user/register' \
      --header 'Content-Type: application/json' \
      --data-raw '{
        "email": "random2@gmail.com",
        "password": "sup233erWE-!@#",
        "fullName": "Random"
      }'
  • now open in browser the following url:

      http://localhost:3000/oidc/auth?client_id=foo&response_type=code&redirect_uri=https%3A%2F%2Fjwt.io&scope=openid&nonce=foobar&code_challenge=LOqTgN1kQhLnRWXY8LQbXN032SBJqCxgCYdTcIoUyto&code_challenge_method=S256
    
  • this will open login page, use the email and password registered earlier to authenticate

  • after clicking Authorize you will be redirect to jwt.io (specified in client metadata and in auth url) with authorization_code in url

  • copy that code and use it to obtain token with following POST request (Basic Authorization header is composed using base64Encode(client_id:client_secret)) replace authorization_code with what you obtained from previous step

      curl --location --request POST 'http://localhost:3000/oidc/token' \
        --header 'Authorization: Basic Zm9vOmZvb2Jhcg==' \
        --header 'Content-Type: application/x-www-form-urlencoded' \
        --data-urlencode 'code=<AUTHORIZATION_CODE_GOES_HERE>' \
        --data-urlencode 'grant_type=authorization_code' \
        --data-urlencode 'redirect_uri=https://jwt.io' \
        --data-urlencode 'code_verifier=_z9u~RxevCk0jbFOfky1xEJcT-60Wgsl2QrU8DvBaNp755VNt8P_vbMKSWn6GIUShBwS~LT5vULj7Qnmt0bk38T8aeOiG3MOLPY~0_5fxW6p3SLbyw0Px.z9JW_hqs6E'
  • response should look like this

      {
          "access_token": "RvKSmu8UjUm_USTOoJQcnxOdXy-M1_MsDPMSy1XzpZ7",
          "expires_in": 3600,
          "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im5JTkxnSkh2UWZVQTVJSWJxR2hNbTJGWDlSNmNMbGJWS182c1FvQXJqMzAifQ.eyJzdWIiOiJsZWR1eW1pbmg0OEBnbWFpbC5jb20iLCJub25jZSI6ImZvb2JhciIsImF0X2hhc2giOiJ2OVNQbWVFTnU4ZXVXZjFyS2pTaDd3IiwiYXVkIjoiZm9vIiwiZXhwIjoxNjI2NTU1MjE4LCJpYXQiOjE2MjY1NTE2MTgsImlzcyI6Imh0dHBzOi8vbG9naW4uZXBhbS5jb20ifQ.kzCqR4KnWfAaLZfnfV3fsvlq4lgl_GaqAB7UuNki5Jx2i_lft4h543XVnwYTm5mVYE9C5i5dgjlXDNSOutNj0ulG0EfzcsVZeE-u3KKf1IgTOL06iH2GNhAaHOSYCbTHDW-icTtC5s5CGNUukBHMcBwPd1Y435YmNTe7NDFBIltiqxRDb4IVOk3Y9a3bdQcSDMqHcCo3PSXc-zaS2z0FcxODc_8_zH_4--lzdBNeDWPZxJx0_i2YPwwm14DeaK7UlJh6euBAkZWQk00XU6KktqVMkGCJFKi6hyjwN5kthEepgSGKEeY8rOoMUS-QnaWGs_JObCB1HNnavseplLDs3g",
          "scope": "openid",
          "token_type": "Bearer"
      }
  • copy id_token to jwt.io debugger, and you can retrieve user_info authenticated earlier

  • this flow can be implemented simply by using oidc-client library