检查用户是否可以连接 Slim 的 RESTful 方式
RESTfull way to check if a user can connect with Slim
我有一个 SLim API,我在我的 ANgularJS 应用程序中使用它来访问我的数据库(例如):
我的控制器:
$scope.testDatabaseItems = function(){
$http.get(pathApi + 'items').success(function(data) {
$log.info("succes!");
$log.log(data);
$scope.items=data;
})
.error(function (data, status){
$log.error("error!");
$log.log(data);
});
};
我的 Slim 应用程序:
<?php
require 'vendor/autoload.php';
require 'config/config.php';
$app = new \Slim\App;
$app->get('/items', 'getItems');
$app->get('/items/{id:\d+}', 'getItemById');
$app->post('/new_user', 'addUser');
$app->get('/users', 'getUsers');
$app->run();
function DB_Connection() {
global $dbparams;
$dbhost = $dbparams['host'];
$dbuser = $dbparams['user'];
$dbpass = $dbparams['password'];
$dbname = $dbparams['dbname'];
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
function getItems() {
$sql = "SELECT * FROM aj_items";
try {
$db = DB_Connection();
$stmt = $db->query($sql);
$list = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode($list);
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
?>
我的问题是我想调用我的 Slim 应用程序来检查用户名和密码是否有效(连接),但我想要一个 RESTfull API 并且我在 RESTfull API,我通常使用其中之一:GET、POST、DELETE 或 PUT。
我不知道我可以使用哪个,因为我只是查看一些信息并将其与 password_verify() 进行比较。我知道我想要 return 2 个特定字段(如果它有效),但是如果我仍然希望我的 API 被视为 RESTfull,我不确定该怎么做。
在涉及 Restful API 的应用程序环境中,建议使用 JSON Web Tokens (JWT) 在各方之间传递声明。
在您的 Slim 应用程序中使用 firebase/php-jwt。
composer require firebase/php-jwt
然后在你的路线中
<?php
require 'vendor/autoload.php';
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
$app = new \Slim\App;
$app->get('/authenticate', function (Request $request, Response $response) {
$key = "example_key";
$token = array(
"iss" => "http://example.org",
"aud" => "http://example.com",
"iat" => 1356999524,
"nbf" => 1357000000
);
$jwt = JWT::encode($token, $key);
$response->getBody->write(json_encode(['token' => $jwt]));
return $response;
});
$app->get('/items', function (Request $request, Response $response){
$key = "example_key";
$token = $request->getHeader('HTTP_AUTHORIZATION');
if (!empty($token) && is_array($token)) {
$token = trim(str_replace('Bearer', '', $token[0]));
if (JWT::decode($token, $key, ['HS256'])) {
// User authentication successful
} else {
// User authentication failed
}
}
});
?>
现在您需要将 /authenticate
返回的 JWT 缓存在某处。使用 window.sessionStorage 是个好主意,因为数据会一直存在,直到浏览器选项卡关闭,more on cookies vs tokens
$scope.testDatabaseItems = function(){
$http.get(pathApi + 'authenticate')
.then(function (response){
if (response.data.token !== undefined && response.data.token.length) {
$window.sessionStorage.token = response.data.token;
}
}, function (reason){
console.log(reason);
}
);
};
此时您需要告诉 Angular 捕获每个请求,在使用拦截器将其发送到服务器之前添加包含 JWT 的授权 header:
var app = angular.module('myApp', []);
app.config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push('AuthInterceptor');
}]);
app.factory('AuthInterceptor', ['$q', '$window', function ($q, $window) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
}
return config;
},
response: function (response) {
return response || $q.when(response);
}
};
}]);
无需进一步配置。在您的应用程序调用 /items
之前,它首先需要调用 /authenticate
之后,JWT 应该作为授权 header 在每个后续请求中发送,直到浏览器 window关闭或 $window.sessionStorage.token
手动重置。
希望这对您有所帮助:)
我有一个 SLim API,我在我的 ANgularJS 应用程序中使用它来访问我的数据库(例如):
我的控制器:
$scope.testDatabaseItems = function(){
$http.get(pathApi + 'items').success(function(data) {
$log.info("succes!");
$log.log(data);
$scope.items=data;
})
.error(function (data, status){
$log.error("error!");
$log.log(data);
});
};
我的 Slim 应用程序:
<?php
require 'vendor/autoload.php';
require 'config/config.php';
$app = new \Slim\App;
$app->get('/items', 'getItems');
$app->get('/items/{id:\d+}', 'getItemById');
$app->post('/new_user', 'addUser');
$app->get('/users', 'getUsers');
$app->run();
function DB_Connection() {
global $dbparams;
$dbhost = $dbparams['host'];
$dbuser = $dbparams['user'];
$dbpass = $dbparams['password'];
$dbname = $dbparams['dbname'];
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
function getItems() {
$sql = "SELECT * FROM aj_items";
try {
$db = DB_Connection();
$stmt = $db->query($sql);
$list = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode($list);
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
?>
我的问题是我想调用我的 Slim 应用程序来检查用户名和密码是否有效(连接),但我想要一个 RESTfull API 并且我在 RESTfull API,我通常使用其中之一:GET、POST、DELETE 或 PUT。
我不知道我可以使用哪个,因为我只是查看一些信息并将其与 password_verify() 进行比较。我知道我想要 return 2 个特定字段(如果它有效),但是如果我仍然希望我的 API 被视为 RESTfull,我不确定该怎么做。
在涉及 Restful API 的应用程序环境中,建议使用 JSON Web Tokens (JWT) 在各方之间传递声明。
在您的 Slim 应用程序中使用 firebase/php-jwt。
composer require firebase/php-jwt
然后在你的路线中
<?php
require 'vendor/autoload.php';
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
$app = new \Slim\App;
$app->get('/authenticate', function (Request $request, Response $response) {
$key = "example_key";
$token = array(
"iss" => "http://example.org",
"aud" => "http://example.com",
"iat" => 1356999524,
"nbf" => 1357000000
);
$jwt = JWT::encode($token, $key);
$response->getBody->write(json_encode(['token' => $jwt]));
return $response;
});
$app->get('/items', function (Request $request, Response $response){
$key = "example_key";
$token = $request->getHeader('HTTP_AUTHORIZATION');
if (!empty($token) && is_array($token)) {
$token = trim(str_replace('Bearer', '', $token[0]));
if (JWT::decode($token, $key, ['HS256'])) {
// User authentication successful
} else {
// User authentication failed
}
}
});
?>
现在您需要将 /authenticate
返回的 JWT 缓存在某处。使用 window.sessionStorage 是个好主意,因为数据会一直存在,直到浏览器选项卡关闭,more on cookies vs tokens
$scope.testDatabaseItems = function(){
$http.get(pathApi + 'authenticate')
.then(function (response){
if (response.data.token !== undefined && response.data.token.length) {
$window.sessionStorage.token = response.data.token;
}
}, function (reason){
console.log(reason);
}
);
};
此时您需要告诉 Angular 捕获每个请求,在使用拦截器将其发送到服务器之前添加包含 JWT 的授权 header:
var app = angular.module('myApp', []);
app.config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push('AuthInterceptor');
}]);
app.factory('AuthInterceptor', ['$q', '$window', function ($q, $window) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
}
return config;
},
response: function (response) {
return response || $q.when(response);
}
};
}]);
无需进一步配置。在您的应用程序调用 /items
之前,它首先需要调用 /authenticate
之后,JWT 应该作为授权 header 在每个后续请求中发送,直到浏览器 window关闭或 $window.sessionStorage.token
手动重置。
希望这对您有所帮助:)