در ادامه ی قسمتهای قبل این سری آموزشها, در این قسمت کار API لاراول رو به اتمام می رسونیم و بخش Angular رو در قسمت بعدی توضیح می دهیم.
پیادهسازی درخواست های POST, PUT, DELETE
فایل کنترلر JokesController.php رو باز کرده و متدهای اون رو بصورت زیر آپدیت کنید.
اول این خط رو بالای کد قرار دهید :
use Illuminate\Http\Request;
سپس بصورت زیر تغییرات رو اعمال کنید :
public function store(Request $request)
{
if(! $request->body or ! $request->user_id){
return Response::json([
'error' => [
'message' => 'Please Provide Both body and user_id'
]
], 422);
}
$joke = Joke::create($request->all());
return Response::json([
'message' => 'Joke Created Succesfully',
'data' => $this->transform($joke)
]);
}
public function update(Request $request, $id)
{
if(! $request->body or ! $request->user_id){
return Response::json([
'error' => [
'message' => 'Please Provide Both body and user_id'
]
], 422);
}
$joke = Joke::find($id);
$joke->body = $request->body;
$joke->user_id = $request->user_id;
$joke->save();
return Response::json([
'message' => 'Joke Updated Succesfully'
]);
}
public function destroy($id)
{
Joke::destroy($id);
}
برای تست درخواست POST افزونه postman رو باز کرده و بصورت زیر درخواست POST رو ارسال نمایید :
درخواست های DLETE و UPDATE رو هم به سادگی میتونید انجام بدید.
صفحه بندی
برای صفحه بندی, لاراول یک متد ساده به اسم ()paginate داره, در ادامه با استفاده از این متد صفحه بندی رو پیادهسازی می کنیم. کنترلر JokesController رو باز کرده و متد index رو بصورت زیر آپدیت نمایید :
public function index(){
$jokes = Joke::with(
array('User'=>function($query){
$query->select('id','name');
})
)->select('id', 'body', 'user_id')->paginate(5);
return Response::json($this->transformCollection($jokes), 200);
}
حالا اگر وارد مسیر شوید به ارور برمیخورید :
مشکل اینه که ما باید متد transformCollection رو در کنترلر JokesController آپدیت کنیم :
private function transformCollection($jokes){
$jokesArray = $jokes->toArray();
return [
'total' => $jokesArray['total'],
'per_page' => intval($jokesArray['per_page']),
'current_page' => $jokesArray['current_page'],
'last_page' => $jokesArray['last_page'],
'next_page_url' => $jokesArray['next_page_url'],
'prev_page_url' => $jokesArray['prev_page_url'],
'from' => $jokesArray['from'],
'to' =>$jokesArray['to'],
'data' => array_map([$this, 'transform'], $jokesArray['data'])
];
}
حالا به مسیر تعیین شده برید و صفحه بندی انجام شده رو مشاهده کنید :
درحال حاضر ما به 5 آیتم در هر صفحه صفحه بندی کردیم اما ما میتونیم از query string هم برای این کار استفاده کنیم :
public function index(Request $request)
{
$limit = $request->input('limit')?$request->input('limit'):5;
$jokes = Joke::with(
array('User'=>function($query){
$query->select('id','name');
})
)->select('id', 'body', 'user_id')->paginate($limit);
$jokes->appends(array(
'limit' => $limit
));
return Response::json($this->transformCollection($jokes), 200);
}
بدین شکل که اگر query string مورد نظر موجود باشه اون درنظر گرفته شه وگرنه عدد 5 جایگزین میشه.
پیادهسازی جستجو
حالا بیایم درمورد نحوه پیادهسازی جستجو صحبت کنیم. اول متد index رو به صورت زیر آپدیت کنید:
public function index(Request $request)
{
$search_term = $request->input('search');
$limit = $request->input('limit')?$request->input('limit'):5;
if ($search_term)
{
$jokes = Joke::orderBy('id', 'DESC')->where('body', 'LIKE', "%$search_term%")->with(
array('User'=>function($query){
$query->select('id','name');
})
)->select('id', 'body', 'user_id')->paginate($limit);
$jokes->appends(array(
'search' => $search_term,
'limit' => $limit
));
}
else
{
$jokes = Joke::orderBy('id', 'DESC')->with(
array('User'=>function($query){
$query->select('id','name');
})
)->select('id', 'body', 'user_id')->paginate($limit);
$jokes->appends(array(
'limit' => $limit
));
}
return Response::json($this->transformCollection($jokes), 200);
}
حالا میتونید بصورت زیر تستش کنید :
افزودن JWT Auth
حالا میخوایم مسیرها رو امنیتی تر کنیم, طوری که فقط کاربران احراز هویت شده بتونند درخواست اطلاعات بدهند و کاربران دیگر خطا دریافت کنند! ما از auth پایه که لاراول فراهم کرده استفاده میکنیم کنترلر JokesController باز کرده و تغییر زیر ایجاد کنید :
public function __construct(){
//$this->middleware('auth.basic', ['only' => 'store']);
$this->middleware('auth.basic');
}
این یعنی استفاده از auth در تمام مسیرها. وقتی ما بخوایم وارد مسیر بشیم ابتدا باید به سیستم وارد بشیم :
اما ما نمیخواهیم از این سیستم برای api خودمون استفاده کنیم چون بهتره از یک سیستم احراز هویت token base استفاده کنیم. که یعنی وقتی کاربر تأیید هویت میشه یک توکن برای تولید میشه و اون هربار توکن رو همراه با درخواستش می فرسته و اگر توکن معتبر بود اطلاعات نمایش داده میشه.
برای اینکار ما از پکیجی به نام jwt-auth استفاده می کنیم.
ابتدا خط زیر رو به فایل composer.json اضافه کنید :
"tymon/jwt-auth": "0.5.*"
سپس دستور زیر رو اجرا کنید :
composer update
بعد از دانلود این پکیج خط زیر رو به providers در فایل config/app.php بیافزایید :
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class
و خطوط زیر رو به قسمت aliases
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class
توسط دستور زیر اون رو منتشر کنید :
php artisan vendor:publish –provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
حالا یک فایل جدید به اسم jwt.php به پوشه کانفیگ اضافه میشه. دستور زیر رو برای ساخت کلید jwt وارد نمایید :
php artisan jwt:generate
حالا فایل routes/web.php باز کرده و خطوط زیر بیافزایید :
Route::group(['prefix' => 'api/v1'], function()
{
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController@authenticate');
Route::get('authenticate/user', 'AuthenticateController@getAuthenticatedUser');
});
حالا middleware رو به کنترلر اضافه کنید :
public function __construct(){
$this->middleware('jwt.auth');
}
و کنترلر AuthenticateController باز کرده و تغییرات زیر رو اعمال کنید :
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\User;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class AuthenticateController extends Controller
{
public function __construct()
{
$this->middleware('jwt.auth', ['except' => ['authenticate']]);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return "Auth index";
}
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
try {
// verify the credentials and create a token for the user
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong
return response()->json(['error' => 'could_not_create_token'], 500);
}
// if no errors are encountered we can return a JWT
return response()->json(compact('token'));
}
public function getAuthenticatedUser()
{
try {
if (! $user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
// the token is valid and we have found the user via the sub claim
return response()->json(compact('user'));
}
}
اگر وارد مسیر /api/v1/jokes بشید با ارور token not provided مواجه میشید.
برای ساخت توکن به api/v1/authenticate رفته و ایمیل و پسورد رو وارد کنید :
حالا میتونید به صورت زیر درخواست رو همراه توکن فرستاده و نتیجه رو ببینید :
مبارزه با CORS
برای اینکه مباحث امنیتی api رو تکمیل کنیم نباید اجازه بدیم کسی با استفاده از cross domain restrictions به api دسترسی پیدا کنه. پس از پکیج laravel-cors استفاده می کنیم.
composer require barryvdh/laravel-cors 0.7.x
افزودن provider :
Barryvdh\Cors\ServiceProvider::class
درنهایت تغییراتی در فایل routes/web.php :
Route::group(['middleware' => 'cors', 'prefix' => 'api/v1'], function()
{
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController@authenticate');
Route::get('authenticate/user', 'AuthenticateController@getAuthenticatedUser');
});
Route::group(['middleware' => 'cors', 'prefix' => 'api/v1'], function(){
Route::resource('jokes', 'JokesController');
});
در قسمت بعد بیشتر درباره بخش Angular صحبت می کنیم.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید