在本教程中,您将学习如何使用PHP和MySQL数据库创建简单的RESTful API登录和注册。
在继续之前,如果您愿意,可以阅读我已经完成的有关如何创建CRUD RESTful API的教程 。也许本教程在这里对您有用。
在本教程中,我们将使用JWT对用户进行身份验证。因此,我建议您首先阅读本教程- 如何使用PHP实现JWT。
MySQL数据库设置
- 数据库名称 –
php_auth_api
- 表名 –
users
在您的MySQL数据库内部,创建一个名为php_auth_api的新数据库 。然后,使用以下SQL代码创建 users
表和该表的结构–
用户表的SQL代码
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, `password` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
创建文件和文件夹
首先,打开 Xampp htdocs 目录或 服务器www 目录,并创建一个名为的新文件夹 php-login-registration-api
。这是我们的应用程序文件夹。
在应用程序文件夹中,我们将创建以下文件和文件夹–
PHP登录注册API文件夹结构
📁jwt文件夹设置
- 从此处下载JWT软件包 。
- 解压缩ZIP文件。
- 将src 文件夹复制到该 文件夹内
php-login-registration-api
。 - 将src 文件夹重命名 为 jwt。
📁classes文件夹设置
现在,在应用程序文件夹中,您必须创建一个名为classes的新文件夹。之后,在classes文件夹内,我们将创建两个文件或类–
Database.php
–用于建立数据库连接JwtHandler.php
–用于处理JWT动作,例如编码和解码令牌
Database.php
<?php
class Database{
private $db_host = 'localhost';
private $db_name = 'phpsamples';
private $db_username = 'phpsamples';
private $db_password = 'phpsamples';
public function dbConnection(){
try{
$conn = new PDO('mysql:host='.$this->db_host.';dbname='.$this->db_name,$this->db_username,$this->db_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}
catch(PDOException $e){
echo "Connection error ".$e->getMessage();
exit;
}
}
}
JwtHandler.php
<?php
require __DIR__.'/../jwt/JWT.php';
require __DIR__.'/../jwt/ExpiredException.php';
require __DIR__.'/../jwt/SignatureInvalidException.php';
require __DIR__.'/../jwt/BeforeValidException.php';
use \Firebase\JWT\JWT;
class JwtHandler {
protected $jwt_secrect;
protected $token;
protected $issuedAt;
protected $expire;
protected $jwt;
public function __construct()
{
// set your default time-zone
date_default_timezone_set('Asia/Kolkata');
$this->issuedAt = time();
// Token Validity (3600 second = 1hr)
$this->expire = $this->issuedAt + 3600;
// Set your secret or signature
$this->jwt_secrect = "this_is_my_secrect";
}
// ENCODING THE TOKEN
public function _jwt_encode_data($iss,$data){
$this->token = array(
//Adding the identifier to the token (who issue the token)
"iss" => $iss,
"aud" => $iss,
// Adding the current timestamp to the token, for identifying that when the token was issued.
"iat" => $this->issuedAt,
// Token expiration
"exp" => $this->expire,
// Payload
"data"=> $data
);
$this->jwt = JWT::encode($this->token, $this->jwt_secrect);
return $this->jwt;
}
protected function _errMsg($msg){
return [
"auth" => 0,
"message" => $msg
];
}
//DECODING THE TOKEN
public function _jwt_decode_data($jwt_token){
try{
$decode = JWT::decode($jwt_token, $this->jwt_secrect, array('HS256'));
return [
"auth" => 1,
"data" => $decode->data
];
}
catch(\Firebase\JWT\ExpiredException $e){
return $this->_errMsg($e->getMessage());
}
catch(\Firebase\JWT\SignatureInvalidException $e){
return $this->_errMsg($e->getMessage());
}
catch(\Firebase\JWT\BeforeValidException $e){
return $this->_errMsg($e->getMessage());
}
catch(\DomainException $e){
return $this->_errMsg($e->getMessage());
}
catch(\InvalidArgumentException $e){
return $this->_errMsg($e->getMessage());
}
catch(\UnexpectedValueException $e){
return $this->_errMsg($e->getMessage());
}
}
}
📁middlewares文件夹设置
现在,在应用程序文件夹中再次创建类之后,创建一个名为的新文件夹 middlewares
。在 middlewares 文件夹中,您只需要创建一个类–
Auth.php
–用于验证令牌(检查令牌是否有效)- 有效令牌 –返回
User
- 无效令牌 –返回
null
Auth.php
<?php
require __DIR__.'/../classes/JwtHandler.php';
class Auth extends JwtHandler{
protected $db;
protected $headers;
protected $token;
public function __construct($db,$headers) {
parent::__construct();
$this->db = $db;
$this->headers = $headers;
}
public function isAuth(){
if(array_key_exists('Authorization',$this->headers) && !empty(trim($this->headers['Authorization']))):
$this->token = explode(" ", trim($this->headers['Authorization']));
if(isset($this->token[1]) && !empty(trim($this->token[1]))):
$data = $this->_jwt_decode_data($this->token[1]);
if(isset($data['auth']) && isset($data['data']->user_id) && $data['auth']):
$user = $this->fetchUser($data['data']->user_id);
return $user;
else:
return null;
endif; // End of isset($this->token[1]) && !empty(trim($this->token[1]))
else:
return null;
endif;// End of isset($this->token[1]) && !empty(trim($this->token[1]))
else:
return null;
endif;
}
protected function fetchUser($user_id){
try{
$fetch_user_by_id = "SELECT `name`,`email` FROM `users` WHERE `id`=:id";
$query_stmt = $this->db->prepare($fetch_user_by_id);
$query_stmt->bindValue(':id', $user_id,PDO::PARAM_INT);
$query_stmt->execute();
if($query_stmt->rowCount()):
$row = $query_stmt->fetch(PDO::FETCH_ASSOC);
return [
'success' => 1,
'status' => 200,
'user' => $row
];
else:
return null;
endif;
}
catch(PDOException $e){
return null;
}
}
}
创建其他文件
现在该创建基础文件了–
register.php
–用于用户注册。login.php
–用于用户登录。user-info.php
–登录后,可使用有效令牌访问该页面。
register.php
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
function msg($success,$status,$message,$extra = []){
return array_merge([
'success' => $success,
'status' => $status,
'message' => $message
],$extra);
}
// INCLUDING DATABASE AND MAKING OBJECT
require __DIR__.'/classes/Database.php';
$db_connection = new Database();
$conn = $db_connection->dbConnection();
// GET DATA FORM REQUEST
$data = json_decode(file_get_contents("php://input"));
$returnData = [];
// IF REQUEST METHOD IS NOT POST
if($_SERVER["REQUEST_METHOD"] != "POST"):
$returnData = msg(0,404,'Page Not Found!');
// CHECKING EMPTY FIELDS
elseif(!isset($data->name)
|| !isset($data->email)
|| !isset($data->password)
|| empty(trim($data->name))
|| empty(trim($data->email))
|| empty(trim($data->password))
):
$fields = ['fields' => ['name','email','password']];
$returnData = msg(0,422,'Please Fill in all Required Fields!',$fields);
// IF THERE ARE NO EMPTY FIELDS THEN-
else:
$name = trim($data->name);
$email = trim($data->email);
$password = trim($data->password);
if(!filter_var($email, FILTER_VALIDATE_EMAIL)):
$returnData = msg(0,422,'Invalid Email Address!');
elseif(strlen($password) < 8):
$returnData = msg(0,422,'Your password must be at least 8 characters long!');
elseif(strlen($name) < 3):
$returnData = msg(0,422,'Your name must be at least 3 characters long!');
else:
try{
$check_email = "SELECT `email` FROM `users` WHERE `email`=:email";
$check_email_stmt = $conn->prepare($check_email);
$check_email_stmt->bindValue(':email', $email,PDO::PARAM_STR);
$check_email_stmt->execute();
if($check_email_stmt->rowCount()):
$returnData = msg(0,422, 'This E-mail already in use!');
else:
$insert_query = "INSERT INTO `users`(`name`,`email`,`password`) VALUES(:name,:email,:password)";
$insert_stmt = $conn->prepare($insert_query);
// DATA BINDING
$insert_stmt->bindValue(':name', htmlspecialchars(strip_tags($name)),PDO::PARAM_STR);
$insert_stmt->bindValue(':email', $email,PDO::PARAM_STR);
$insert_stmt->bindValue(':password', password_hash($password, PASSWORD_DEFAULT),PDO::PARAM_STR);
$insert_stmt->execute();
$returnData = msg(1,201,'You have successfully registered.');
endif;
}
catch(PDOException $e){
$returnData = msg(0,500,$e->getMessage());
}
endif;
endif;
echo json_encode($returnData);
login.php
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
function msg($success,$status,$message,$extra = []){
return array_merge([
'success' => $success,
'status' => $status,
'message' => $message
],$extra);
}
require __DIR__.'/classes/Database.php';
require __DIR__.'/classes/JwtHandler.php';
$db_connection = new Database();
$conn = $db_connection->dbConnection();
$data = json_decode(file_get_contents("php://input"));
$returnData = [];
// IF REQUEST METHOD IS NOT EQUAL TO POST
if($_SERVER["REQUEST_METHOD"] != "POST"):
$returnData = msg(0,404,'Page Not Found!');
// CHECKING EMPTY FIELDS
elseif(!isset($data->email)
|| !isset($data->password)
|| empty(trim($data->email))
|| empty(trim($data->password))
):
$fields = ['fields' => ['email','password']];
$returnData = msg(0,422,'Please Fill in all Required Fields!',$fields);
// IF THERE ARE NO EMPTY FIELDS THEN-
else:
$email = trim($data->email);
$password = trim($data->password);
// CHECKING THE EMAIL FORMAT (IF INVALID FORMAT)
if(!filter_var($email, FILTER_VALIDATE_EMAIL)):
$returnData = msg(0,422,'Invalid Email Address!');
// IF PASSWORD IS LESS THAN 8 THE SHOW THE ERROR
elseif(strlen($password) < 8):
$returnData = msg(0,422,'Your password must be at least 8 characters long!');
// THE USER IS ABLE TO PERFORM THE LOGIN ACTION
else:
try{
$fetch_user_by_email = "SELECT * FROM `users` WHERE `email`=:email";
$query_stmt = $conn->prepare($fetch_user_by_email);
$query_stmt->bindValue(':email', $email,PDO::PARAM_STR);
$query_stmt->execute();
// IF THE USER IS FOUNDED BY EMAIL
if($query_stmt->rowCount()):
$row = $query_stmt->fetch(PDO::FETCH_ASSOC);
$check_password = password_verify($password, $row['password']);
// VERIFYING THE PASSWORD (IS CORRECT OR NOT?)
// IF PASSWORD IS CORRECT THEN SEND THE LOGIN TOKEN
if($check_password):
$jwt = new JwtHandler();
$token = $jwt->_jwt_encode_data(
'http://localhost/php_auth_api/',
array("user_id"=> $row['id'])
);
$returnData = [
'success' => 1,
'message' => 'You have successfully logged in.',
'token' => $token
];
// IF INVALID PASSWORD
else:
$returnData = msg(0,422,'Invalid Password!');
endif;
// IF THE USER IS NOT FOUNDED BY EMAIL THEN SHOW THE FOLLOWING ERROR
else:
$returnData = msg(0,422,'Invalid Email Address!');
endif;
}
catch(PDOException $e){
$returnData = msg(0,500,$e->getMessage());
}
endif;
endif;
echo json_encode($returnData);
user-info.php
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
require __DIR__.'/classes/Database.php';
require __DIR__.'/middlewares/Auth.php';
$allHeaders = getallheaders();
$db_connection = new Database();
$conn = $db_connection->dbConnection();
$auth = new Auth($conn,$allHeaders);
$returnData = [
"success" => 0,
"status" => 401,
"message" => "Unauthorized"
];
if($auth->isAuth()){
$returnData = $auth->isAuth();
}
echo json_encode($returnData);
测试API
🔗API URL –
// Register
http://localhost/php-login-registration-api/register.php
// Login
http://localhost/php-login-registration-api/login.php
// Get User Info by giving token
http://localhost/php-login-registration-api/user-info.php
👉注册用户
注册用户API测试
👉登录用户
登录用户API测试
通过提供令牌来获取用户信息
- 标头密钥名称:Authorization
- 钥匙的值:
Bearer your_token
GitHub下载源码