Join us
@fulviodenza ・ Jan 22,2022 ・ 3 min read ・ 7900 views ・ Originally posted on faun.pub
This article will contain a lot of code snippets. All code is retrievable here: https://github.com/fulviodenza/cognito-golang
This is not production-ready code, you should add some other checks, wrap errors from Cognito to make them less user-affordable, integrate Cognito with Amplify and other things we’re not interested in.
Writing an Authentication service for a Golang project using AWS Cognito is quite simple if you know where to search for information.
Let’s start from the beginning.
Set up Cognito
What is AWS Cognito?
Amazon Cognito provides authentication, authorization, and user management for your web and mobile apps. Your users can sign in directly with a user name and password, or through a third party such as Facebook, Amazon, Google or Apple.
In this article, we’ll talk about how to perform various operations just with username and password using the AWS SDK library (https://github.com/aws/aws-sdk-go) and the Echo web framework.
First of all, let’s create a User Pool, a user pool is a user directory in Amazon Cognito, this will contain all information to access your web application.
From the AWS reach the Cognito page and Create User Pool as shown below:
After this step, we’ll have to proceed with some configurations:
2. Next we’ll have to select Password Policy, MFA and User account Recovery, select your preferred configurations.
In this guide we’ll use the following configuration:
Password Policy: Cognito Default
Multi-factor authentication: Authenticator Apps
User Account Recovery: Enable self-service account recovery — Recommended (Email Only)
3. Configure sign-up experience: Let’s keep it as is (Email verification.
4. Configure message delivery: Let’s select “Send Email with Cognito” and create a new IAM Role called “email-cognito"
5. Integrate your app: Now we should decide the user pool name, userpool-example, the type of Client, Public Client, the app client name, appclient-example.
6. Create User Pool!
Types definition
Now we’re almost ready to go, user pool has been created:
Let’s step onto Go code, starting with types definition:
Ok, now things get complex.
I’ll define each struct what does it mean:
The App struct contains each key useful for the user pool connection. Each of these keys is retrievable from the AWS console. These keys should be kept privates and not shared with anyone.
The User struct contains fields for user recognizing. Fields self-explanatory
UserRegister and UserConfirmationCode extend User struct adding a field for Email registration (for the first one) and a field for OTP verification at Forgot Password time (for the second one).
UserForgot instead is used for Forgot Password operation. It requires just the Username field, the password is (obviously) not required.
Finally, the OTP type is used for user verification at login time. This requires just the OTP received via mail and the username the user is logging.
Response and CustomValidator are used for the Echo framework and are not required for Cognito authentication.
Function Definition
Helper functions
We’ll see these 3 recurrent functions:
Validate: validates the JSON in the user request body
validateUser: validates the nested structure User in the UserRegister and UserConfirmationCode
computeSecretHash: Given the secret token, calculates the hash
Registration
The register receiver method is the handler for the /register endpoint, this method takes echo.Context in which is located the user input as JSON request as input with the following format:
and returns a JSON response containing the error with the following format:
Message string could also be empty.
SignUp function registers the user in the specified user pool and creates a user name, password, and user attributes. This action might generate an SMS text message.
Login
The login receiver method is the handler for /login endpoint, this method takes echo. Context as a parameter in which is located the user input as JSON request as input with the following format:
and returns a JSON containing the error with this format:
The function InitiateAuth function Initiates the authentication flow. This action, as described in the documentation, might generate an SMS text message.
OTP
OTP receiver method is the handler for /otp endpoint, this method takes echo.Context in which is located the user input as JSON request as input with the following format:
otp field is received via email and returns a JSON containing the error with this format:
ForgotPassword
This is the function to reset the password. ForgotPassword method triggers an email sending which will contain otp code for verifying the email.
This otp code will be submitted from the user using the below ConfirmForgotPassword function.
Logout
Logout can be performed simply by revoking the user access token in the App.Token field passing it to the function:
Main Function
The main function is the function to initialize endpoints and set up echo stuff here is the code.
Conclusions
Cognito is a very useful tool that, combined with tools like Amplify, could make a great difference in releasing a project which includes authentication.
I wrote this article because I noticed a lack of documentation for writing an authentication service using Golang+Cognito.
If you find any issue in this article, please notify me.
Join other developers and claim your FAUN account now!
Influence
Total Hits
Posts
Only registered users can post comments. Please, login or signup.