.::Author : Tasos Adamopoulos
.::Description :
Build a Symfony PHP project that we can run on a local domain, and has the following specifications
• it must use Symfony and Doctrine
• there are users and api keys stored in mysql tables
• every time a user makes a call, the call details are logged in a table called Log
• given an api key that belongs to user 1, we can make a call (e.g. with Postman) to /user/1
and get a JSON back with the user 1 details. API key can be inserted in a header or in a cookie.
• users should only be able to access their own user with their key. All attempts to access
another user return an error
• All errors are handled nicely. e.g. wrong api key, no api key, non existing users, non
existing resources
That's all. You can also include a setup SQL (that includes users 1 and 2 and keys)
and some instructions of how to set up.
.::Info
This symfony app is simple User Authentication JSON Endpoint . A user can make a call
through postman or curl . An API key should exist at requests header as 'user info' .
App has been tested with curl through a bash script (client calls tested on MacOSX 11.11.04).
You can find Server's specs bellow :
.::System Specs:
Linux : ARCH 2017
Apache : 2.4.25
MySQL : 10.1.24-MariaDB
PHP : 7.1.6
Symfony : 3.3.2
.::User / API key pairs:
Assume that 2 users are stored in our system , (1) George Best and (2) Michael Schumacher
Every user has an API key that has to be included at calls header .
user 1 / b48d0416-bc38-467d-8066-cd14bb7ead5e user 2 / b71fe516-efc2-479f-a986-4c58ae7b2ea8
.::SQL CODE :
-Our app's DB configuartion :
database php driver : mysqli -( MODULE SHOULD BE ACTIVATED AT php.ini ! )
database host: 127.0.0.1
database port: null
database name: authentication
database user: auth
database password: 123456
-The following MySQL code should be executed to create the DB we need :
CREATE DATABASE authentication;
USE authentication;
CREATE USER 'auth'@'localhost' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON authentication . * TO 'auth'@'localhost';
CREATE TABLE log (id INT AUTO_INCREMENT NOT NULL,
userid INT NOT NULL,
success TINYINT(1) NOT NULL,
info VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE user_details (id INT AUTO_INCREMENT NOT NULL,
name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE secret (id INT AUTO_INCREMENT NOT NULL,
userid INT NOT NULL,
apikey VARCHAR(40) NOT NULL,
UNIQUE INDEX UNIQ_5CA2E8E5F132696E (userid),
UNIQUE INDEX UNIQ_5CA2E8E5B84757A1 (apikey), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
INSERT INTO user_details (name,last_name,created_at) VALUES ('George','Best',NOW());
INSERT INTO user_details (name,last_name,created_at) VALUES ('Michael','Schumacher',NOW());
INSERT INTO secret(userid,apikey) VALUES ('1','b48d0416-bc38-467d-8066-cd14bb7ead5e');
INSERT INTO secret(userid,apikey) VALUES ('2','b71fe516-efc2-479f-a986-4c58ae7b2ea8');
-Our DataBase should look like this :
SHOW TABLES;
+--------------------------+
| Tables_in_authentication |
+--------------------------+
| log |
| secret |
| user_details |
+--------------------------+
SELECT * FROM log;
Empty set (0.00 sec)
SELECT * FROM secret;
+----+--------+--------------------------------------+
| id | userid | apikey |
+----+--------+--------------------------------------+
| 1 | 1 | b48d0416-bc38-467d-8066-cd14bb7ead5e |
| 2 | 2 | b71fe516-efc2-479f-a986-4c58ae7b2ea8 |
+----+--------+--------------------------------------+
SELECT * FROM user_details;
+----+---------+------------+---------------------+
| id | name | last_name | created_at |
+----+---------+------------+---------------------+
| 1 | George | Best | 2017-06-29 20:20:37 |
| 2 | Michael | Schumacher | 2017-06-29 20:20:57 |
+----+---------+------------+---------------------+
.::Execution and Deployment Tutorial
At current time app is at Development mode and our service could be accessed through auth/web/app_dev.php
For security reasons servers and clients ip should be stored as "trusted" at auth/web/app_dev.php @ line 15
by default .
To turn to Production mode you can follow this tutorial : https://symfony.com/doc/current/deployment.html
To make a call using curl :
curl <URL: xxx/auth/web/app_dev.php/user/{id}> -u <API KEY>:
Our service responds with a JSON that contains ERROR messages if credentials does not match or users
details if authenticated successfully . For more info about service's response : test/test.txt
.::TEST CALLS :
I used curl to test the service in an automated way (bash script)
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/1
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/2
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/5
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/1 -u b48d0416-bc38-467d-8066-cd14bb7ead5e:
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/2 -u b48d0416-bc38-467d-8066-cd14bb7ead5e:
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/5 -u b48d0416-bc38-467d-8066-cd14bb7ead5e:
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/1 -u b71fe516-efc2-479f-a986-4c58ae7b2ea8:
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/2 -u b71fe516-efc2-479f-a986-4c58ae7b2ea8:
curl 192.168.1.55/symfony/auth/auth/web/app_dev.php/user/5 -u b71fe516-efc2-479f-a986-4c58ae7b2ea8:
- automated test could be found at test/test.sh
- test results could be found at test/test.txt
.::Tutorials that I used :
Symfony and HTTP Fundamentals
https://symfony.com/doc/current/introduction/http_fundamentals.html
Controller
https://symfony.com/doc/current/controller.html
Place API key in Headers or URL
https://stackoverflow.com/questions/5517281/place-api-key-in-headers-or-url
Doctrine
https://symfony.com/doc/current/doctrine.html