# How to implement login system using DynamoDB - By Rahul Ahire

Login system is perhaps the most important component of any modern application. With the rise of serverless adoption in IT, we also need to look forward to adapt our application according to the suitable stack. DynamoDB being one of the most popular NoSQL database in AWS serverless jungle, Let see an basic example of how we can implement sign-in/up functionality.

Now, before going ahead one thing I'd like to mention that we all know there's a lot of aspect that goes into build a safe and secure login feature i.e. SSO, OAuth, JWT, Passwords, etc. But to simplify stuff little bit, we aren't gonna talk about it. Instead, let assume to make an application just by entering an email address just for sake of understanding it.

Traditionally, we had two option `Sign-in` and `Sign-up` on any website. So according to that let's create 2 Lambda function to handle that task like the following image.

![dynamodb login blog – lambda ddb flow.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1639138603977/rfyRL8ljX.png)
so the `/sign-in` and `/sign-out` with go to respective lambda handler.

Before proceeding any further, We need to look upon the layout/design of our DynamoDB table during its creation. Assuming that every email id on earth is unique, all we need is a single index or what DynamoDB would like to call it as a **Primary Key** in their technical vocabulary.

 First let's see the code to create our DynamoDB table from local computer using **Node.js**
```js
const AWS = require('aws-sdk');

const dynamodb = new AWS.DynamoDB({
	region: 'ap-south-1'
});

var params = {
	TableName: 'itemOps',
	AttributeDefinitions: [
		{
			AttributeName: 'email',
			AttributeType: 's'
		}
	],
	KeySchema: [
		{
			AttributeName: 'email',
			KeyType: 'HASH'
		}
	], 
	BillingMode: 'PAY_PER_REQUEST'
};
//documentClient dont support creation of Table

dynamodb.createTable(params, function(err, data) {  
	if (err)
		console.log(err, err.stack); // an error occurred
	else console.log(data); // successful response
});
```

What it does is, it creates the table like below

email    	| attribute(info)
------ | ------
abc@abc.com| [...data] 
xyz@abc.com | [...data]

Essentially we specified in params that create a table `itemOps` which only contains one index i.e `email`.

```
var params = {
    TableName: 'itemOps',
    AttributeDefinitions: [
        {
            AttributeName: 'email',
            AttributeType: 's'
        }
    ],
};
```
Lets starts implementing a `sign-up` function. We'll ignore the lambda handler code for now and straightaway see how can we do that.

Initially you might think to check if user exists or not is, first try to use [`getItem`](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#getItem-property) and use `try` and `catch` block to do post processing. Well, you can do that but its unnecessary extra round trip which is comparatively expensive. Instead, DynamoDB offers you a parameter called `ConditionalExpression` i.e its a way to set condition before doing something.

These are the six conditions you can use in DynamoDB.

- `attribute_exists`
- `attribute_not_exists`
- `attribute_type`
- `begins_with`
- `contains`
- `size`

**1.**  For `Sign-up`, we need to add data when the email isn't present in our table. For that `attribute_not_exists` is perfect for us.
```
ConditionExpression: 'attribute_not_exists(email)'
```
```
const AWS = require('aws-sdk');

const docClient = new AWS.DynamoDB.DocumentClient({
	region: 'ap-south-1'
});

var params = {
	TableName: 'itemOps',
	Item: {
		email: 'abc@example.com',
		data:'this is a random data'
	},
	ConditionExpression: 'attribute_not_exists(email)' // <------- here
};

docClient.put(params, function(err, data) {
	if (err)
		console.log(err, err.stack); // an error occurred
	else console.log(data); // successful response
});
```
**2.**  Same is the case for `Sign-in`, except we need to use this `attribute_exists`
```
 ConditionExpression: 'attribute_not_exists(email)'
```
and the code remains the same except for conditional expression.
```
const AWS = require('aws-sdk');

const docClient = new AWS.DynamoDB.DocumentClient({
	region: 'ap-south-1'
});

var params = {
	TableName: 'itemOps',
	Item: {
		email: 'abc@example.com',
		data:'this is a random data'
	},
	ConditionExpression: 'attribute_exists(email)' // <------- here
};

docClient.put(params, function(err, data) {
	if (err)
		console.log(err, err.stack); // an error occurred
	else console.log(data); // successful response
});
```
not that you know how to use these terms, you can go on to make it complex enough with other things to be useful in real scenario.

To know more about the various DynamoDB terminology, [visit this github page](https://github.com/MeRahulAhire/The-Ultimate-DynamoDB-Course/blob/master/attributeExpression/README.md)

This blog was inspired from my **Ultimate DynamoDB Course** The most effortless way to master DynamoDB in just few days. [Learn more](https://rahulahire.com/dynamodb).

![The Ultimate DynamoDB Course - Google Chrome 10-12-2021 20_16_31.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1639147810584/vnZDGS5TT.png)

If you have any thoughts, suggestion or feedback, Please do let me know about it in comment section.
