Figuring out a verification system via email link
Tags: beginners, php, mysql
Published: 2021-05-30 21:57:02

Hi everyone,

Today i'm doing a verification system for the important changes in our site, like changing your email or resetting your password. For this article lets simulate an email change.

#### Why send email?

Obviously, we need to send an email to the new email address, which will indicate that the new email address is **in use** and **reachable**, for the cases like if the user forgets his/her password. I wont be showing how i send emails to users but if you're curious, i'm using PHPMailer.

#### Keep the changes until confirmed

User entered his/her new email address, but the changes won't be applying until the user goes to the verification link, which we sent to the new email address. So, when the user goes into the link, and it's time to apply the changes, how do we know what changes the user made? For that, we're going to store the changes in our database. 

#### Database table for verification

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfbddt3j5k01equovcqy.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3kjrc1dkrspd43a1nn7.png)

When a user wants to make a change that requires email verification, a row is created in _verification_ table. This table contains:

 `status`: Helps us to track if this verification link is used and the changes applied.
 `email`: Email address to send the verification link.
 `title`: Title of the email.
 `description`: Context of the email.
 `link`: Url with a key that directs to our site.
 `changes`: Changes that we will be applying once the user goes to the link that we have sent.
 `user/admin id`: Refers to the user/admin and lets us know whose changes we are applying.

I will be talking in detail about 2 columns in this row: `link` and `changes`:

* **Link**

Link is a url that we will be using for both direction and finding the row related to that link in the _verification_ table.

Example of a `link`:
`http://satis.emirhakan.com/panel/verification/ADOI8U7oCXOJoJJxBDMF3e`

Let's examine the `key` part of it:
```
| Ver. Type |  Random Gen. String | Hex. Id |
|-----------|---------------------|---------|
|    "A"    |"DOI8U7oCXOJoJJxBDMF"|   "3e"  |
```

`Verification Type`: First character of a `key`. Lets us know what type of a verification this is, for example: "A" is for confirming email address, and "B" is for resetting password. This allows us to generate different styled pages on different verification types.

`Random Generated String`: Next 19 characters of a `key`. This random string allows us to compare the **url** in the address bar  with the **url** in the `link` column of a _verification_ row. In short this part distinguishes a `link` from others.

`Hexadecimal Id`: Last couple characters after the 20th character of a `key`. It's the id of the _verification_ row but transformed to hexadecimal. In this case "3e" in hexadecimal base is equal to  "62" in decimal base. We check the related _Verification_ row based on this id number.

* **Changes**

Changes are the pending changes due to their importance. They will be applied once the user goes to the link related to those changes. After they are applied, `status` of that _verification_ row will be set to 1 to make it unusable, preventing any conflict and duplication in the database.

Example of a `changes` column:
`{"Admin":{"email":"me@emirhakan.com"}}`

Let's examine parts of a `changes` column:
```
             |        Change Object         |
             |------------------------------|
| Table Name | Col. Name |       Value      |
|------------|-----------|------------------|
|   "Admin"  |  "email"  |"me@emirhakan.com"|
```

`Table Name`: The table where changes will be made. Changes can be made in 1 table at a time.

`Change Object`: Overall, the object that contains the change with its key. There can be multiple objects in a `changes` column. e.g.
`{"User_credit":{"credit_num":"4111111111111111"},{"exp_date":"02/22"}}`

`Column Name`: The column that is going to be updated.

`Value`: The value that will be put in the column.

#### Implementing this idea to our site

##### Creating and sending verification link via email

A _Verification_ row is created when an important change is submitted.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/evjt9rf3qbkl6u51cg5n.gif)

In our case, we're only changing our email. A submitted form goes through different processes, but eventually it will come to the **api**, where server-side operations are made.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g61fu2qizy2ms0u0qbw3.png)

In the _Update admin email_ section, we're preparing all the necessary variables such as `link` and `changes`. 
Below that, in the _Create verification data_ section we're inserting _Verification_ row in our database.

Finally, in the _Update link_ section, we're adding the hexadecimal id of the _Verification_ row in the end of the `link`. Then, as you can see, we're running the `SendMail` function.

At this point, we have created a _Verification_ row with the `link` and the `changes` inside, then we have sent an email to the user with the same `link` attached.

##### Using the email link and confirming our changes

Lets use our email link.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/poz82i1o13jg660l9izi.gif)

When a url with a **verification** link is entered in the address bar, it will go to the **api**.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ry6zn230spsvy8men57.png)

Right below the `case 'vercheck'`, we are splitting the `link` and preparing variables. In the first 2 cases of the `switch(true)`, we're checking the `link` and comparing it to it's match in the database.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cr82ilc3vnv3v1eblpkb.png)

In `default:`, now we know the `link` is correct and it belongs to a user and we are ready to apply the changes. We fetch the `changes` column to disassemble it at the `foreach` block. Through this process we also apply the changes.

After finishing applying the changes, we are ready to update the related _Verification_ row and change its `status` to 1.

At the end, we return the status and finally, we have completed the verification process.

#### We have accomplished a verification system that works via email links

I'm a beginner in development, my logic and code might not be so effective and correct, but i wanted to share my thoughts and process of developing a verification system. 

Thank you all for reading.