Generate JWTs with Swift on AWS Lambda
Tags: ios, swift, tutorial, beginners
Published: 2021-03-12 13:07:48

---
title: Generate JWTs with Swift on AWS Lambda
published: true
tags: iOS, Swift, Tutorial, Beginners
canonical_url: https://getstream.io/blog/swift-aws-lambda-jwt/
cover_image: https://i.imgur.com/akkUAAt.png
---

Authorization is one of the essential parts of any iOS application. Once a user is logged in, it's your authorization scheme that will make sure users can't interact with your app in ways they're not allowed to. Without a robust authorization scheme, hackers could easily access sensitive user data and engage in other damaging activities such as scamming. 

Thankfully, the widespread use and standardization of [JWT (JSON Web Tokens)](https://jwt.io/) have made robust and cryptographically secure authorization more straightforward to achieve.

In this article, we'll use [Stream Chat](https://getstream.io/chat/) as an example service to authorize our users for using [Swift Lambda](https://github.com/getstream/swift-lambda/) to generate JWTs. You can then use the JWT for interacting with the Stream Chat service via the [REST API](https://getstream.io/chat/docs_rest/) or by configuring the [iOS Chat SDK](https://getstream.io/chat/sdk/ios/).

## What is JSON Web Token?

> JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
> - [Introduction to JSON Web Tokens](https://jwt.io/introduction)

## How does it work?

After authenticating with a login and password or another method, the user receives a JWT. After authentication, the user will attach this JWT to every request as a way of proving their identity and permission to access a particular resource. This JWT was signed by your server during authentication using a secret key and is verified in subsequent requests.

## Set Up Swift Lambda

Since JWTs should be generated and verified server-side, we can [set up an AWS Lambda written in Swift](https://getstream.io/blog/swift-lambda-aws-serverless/) to do that job. You can choose an alternative method and language, but the next steps will be different. By the end, we'll have an HTTP endpoint that outputs a JWT for a specific user id to access [Stream's chat service](https://getstream.io/chat/).

### Install Kitura's Swift-JWT

To generate a JWT, we'll use [Kitura's Swift-JWT](https://github.com/Kitura/Swift-JWT) package, which takes care of the heavy lifting of building a JWT.

To install it, open your Swift Lambda's `Package.swift` in its root folder and add `.package(name: "SwiftJWT", url: "https://github.com/Kitura/Swift-JWT.git", from: "3.6.2")` to the package's dependency list. Also, add `"SwiftJWT"` to the Lambda target's dependency list. By the end, your Package.swift will look similar to the one below.

{% gist https://gist.github.com/cardoso/3d82dd9ec55fedf57feb84746b607218 %}

## Install OpenSSL

Swift-JWT depends on the OpenSSL library to perform cryptographic operations. To install it, add `RUN yum -y install openssl-devel` to your Swift Lambda's Dockerfile which can be found in its root folder. The Dockerfile should look similar to the one below.

{% gist  https://gist.github.com/cardoso/c5d2acb4ff5ae69e81d93ab68ac4b8ae %}

## Configure Endpoint

Finally, we'll need our endpoint to accept `POST` requests, since we'll send credentials in the request body. To do that, change the Swift Lambda's `serverless.yml` line from `method: get` to `method: post`. It will look similar to the snippet below.

{% gist https://gist.github.com/cardoso/ff4aa1a41caeef5b526af2f8fa35f310 %}

## Parse Request

After you're done configuring your Swift Lambda, we can start writing code in `Sources/Lambda/main.swift`. The code we need will parse a POST request and extract the `user_id` field from its JSON body. After that, it will generate a JWT for that user id and return it.

{% gist https://gist.github.com/cardoso/e56af370f49f9e623574a4443394754b %}

We'll implement the `generateJWT(for userId: String)` function in the next steps.

## Sign Up to Stream

Before we can generate a JWT, we need a secret to sign it. You can get one by [signing up to Stream](https://getstream.io/chat/trial/) or by accessing the [dashboard](https://getstream.io/dashboard/).

![Image shows secret in Stream dashboard](https://i.imgur.com/Kol4QHj.png)

## Generate JWT

To generate a JWT, we'll use SwiftJWT. First, we need to declare a struct conforming to the `Claims` protocol with a `user_id` property of type `String`. That's the only claim required by Stream. After that, we create a JWT object with the user_id claim and sign it using your Stream secret.

{% gist https://gist.github.com/cardoso/cc17ebb764602b1a474a7bc635d2db1f %}

Note: Before you generate a JWT, it's essential to verify the request with some form of authentication such as a password and return `401 Unauthorized` if it's wrong.

## Deploy

The main advantage of using [Swift Lambda](https://github.com/GetStream/swift-lambda) is that it's possible to iterate fast with it. After writing the JWT code, just run the `./Scripts/deploy.sh` script again and wait a few seconds.

![This image shows the deploy script finishing successfully](https://i.imgur.com/PMOl2nU.png)

## Test the Endpoint

To test the endpoint and get a JWT, you can use the following curl command in your terminal. Don't forget to replace the URL with the one you got in the deploy step and change the user id if you want to.

{% gist https://gist.github.com/cardoso/befe62f632132f7ffc63e1e21f98cf33 %}

After running that command, you should get a valid JWT. If it has a `%` at the end, ignore it.

![Image shows curl command running and a JWT output](https://i.imgur.com/jQdgfer.png)

## Conclusion

Congratulations! You've generated a valid JWT for interacting with the Stream Chat service via the [REST API](https://getstream.io/chat/docs_rest) or by configuring the [iOS Chat SDK](https://getstream.io/chat/sdk/ios.). This logic can be adapted to work with other JWT-based services such as [Auth0](https://auth0.com/) and [Dolby.io](https://dolby.io/). To find out what else you can build with Swift on AWS Lambda, check out the [Swift Lambda repository on GitHub](https://github.com/getstream/swift-lambda/).