Tutorial: Securing API Endpoints

Describing The API

The swagger specifications for this API is available in YourAPIExpert’s GitHub repository so I will only detail the critical excerpts here.

Specifying Username and Password Query Parameters

We covered the basics of writing Swagger specifications in our previous API.  Today we will supplement that knowledge by introducing query parameters.  These are parameters which are appended to the URL query string during a request.  If you’ve ever inspected a URL and noticed extra parameters after the URL (?post=1213&action=edit) those would be the query parameters.

In our API we will make use of the query parameters to request the user’s credentials.

paths:
  /user/login:
    get:
      description: 'Exchanges credentials for a JWT access token.'
      operationId: Post_Login
      tags:
        - authorize
      parameters:
        - description: 'The username of the person requiring access.'
          in: query
          name: username
          type: string
          required: true
        - description: 'The password of the person requiring access.'
          in: query
          type: string
          name: password
          required: true
      responses:
        '200':
          description: Successful response
          schema:
            $ref: '#/definitions/jwtResponse'
        '400':
          description: Error response
          schema:
            $ref: '#/definitions/error'
      security: []
      summary: Exchanges user credentials for access token.

Lines 36 – 63 of the Swagger specifications describe the login endpoint.  On line 44 and 49 we specify that the parameters are to be included in the query string.

Let’s take a look now at the expected response.

definitions:
  jwtResponse:
    properties:
      success:
        properties:
          code:
            type: integer
            format: int16
            description: HTTP status code
          status:
            type: string
            description: HTTP status text
          message:
            type: string
            description: HTTP status message
        type: object
      access_token:
        type: string
        description: JWT access token
      expires_in:
        type: string
        description: Token validity in seconds
      refresh_token:
        type: string
        description: Token to exchange for new access token
    type: object

Lines 82 to 107 describe the response to our login request which, if successful, will contain a signed JWT token as well as a faux refresh token.  We have no mechanism to make use of the refresh token at this stage but stay tuned.  Included in the response is a parameter named ‘expires_in’ which will denote the TTL (time-to-live) of the token after which it is no longer valid.

Making Use Of The Access Token

On successful authentication to our ‘login’ endpoint we will be returned an access token, a refresh token and a TTL value.  The access token is largely beneficial because with this in hand we no longer need to pass our username and password for every request and therefore the scheme is more secure.  When our access token has expired we can make use of the refresh token to ‘trade’ for a new access token and refresh token meaning that we almost never need to send the username and password.

To pass the access token I will introduce you to yet another way to send information to APIs – that is via the HTTP header.  Ordinarily these headers are properties of a global nature and specify, for example, the types of responses the application is capable (or willing) to accept, the encoding scheme used for strings and other connection attributes.  Authentication is also amongst the valid definition of ‘connection attributes’.

In our API we will make use of the HTTP header to pass the token but let’s first take a look at what it looks like in a Swagger definition.

  /user/profile:
    get:
      security:
        - JWT: []
      description: 'Verifies a JWT and returns the token contents.'
      operationId: Get_Profile
      tags:
        - profile
      responses:
        '200':
          description: Successful response
          schema:
            $ref: '#/definitions/jwtProfile'
        '400':
          description: Error response
          schema:
            $ref: '#/definitions/error'
      summary: Verifies JSON Web Token.

Lines 64 to 81 show us the definition of the ‘profile’ endpoint.  On successful verification of the token our API will simply display its decoded output.  Pay special attention to lines 66 and 67 where Swagger provides us a special way to define authentication schemes.

securityDefinitions:
  JWT:
    type: apiKey
    name: Authorization
    in: header

Between lines 30 and 34 of the Swagger specifications we defined the ‘JWT’ authentication scheme which allows us to conveniently reference it within endpoints.  Pay special attention to line 34 where we indicate that this parameter is to be sent in the HTTP header.

Up Next: Inspecting The Code

Pages: 1 2 3 4 5

Written by YourAPIExpert