라라벨로 배우는 실전 PHP 웹 프로그래밍
PART 1 라라벨 입문
8. 컨트롤러
8.1 컨트롤러 만들기
라우트 파일을 열어, / 라우트의 처리 로직을 ‘WelcomeController@index’로 연결 한다.
routes/web.php
1
Route::get('/', 'WelcomeController@index');
아티즌 명령줄 인터페이스로 WelcomeController를 만든다. 만든 컨트롤러는 app/Http/Controller 디렉터리 아래에 있다.
code
1
2
$ php artisan make:controller WelcomeController
# Controller created successfully.
NOTE 라라벨 5.1 의 make:controller 명령은 리소스 컨트롤라가 기본값이라 빈 컨트롤러를 만드려면 –plain 옵션을 부여해야 한다. 라라벨 5.2와 5.3은 반대로 기본값이 빈 컨트롤러다
1
php artisan make:controller WelconmeController --plain
index 메서드에 블레이드때 사용한 뷰를 반환한다. (참고로 다른 부분에서도 사용해야 하기 때문에 public 선언을 해야 한다)
8.2 RESTFul 라우트와 컨트롤러
초기 URL을 보는 관덤은 두가지였다. 하나는 /getDog?id=1 처럼 파라미터를 가지고 원격 컴퓨터에 있는 API를 호출로 보는 관점이다.이를 RPC(Remote Procedure Call)이라고 한다. 다른 하나는 URL을 원격 컴퓨터의 리소스로 생각하는 관점이다. 원격컴퓨터의 리소스는 시간에 따라 그 상태가 변할 수 있는데, 클라이언트와 서버가 상태를 교환하기 때문에 REST(REpresentational State Transfer)라고 부른다. REST는 URL 경로를 명사로 사용한다. 구글을 비롯한 인터넷 거물들의 웹 API를 보면 모두 REST 원칙을 따른다는 것을 알 수 있다.
8.2.1 RESTful 리소스 컨트롤러 만들기
RESTfull 리소스 컨트롤러는 REST 원칙에 따라 URL을 컨트롤러 메서드에 자동으로 련결한다. –resource 옵션을 줘서 새로운 컨트롤러를 생성한다.
컨트롤러 뼈대 코드 만들기
1
2
$ php artisan make:controller ArticlesConroller --resource
Controller created successfully.
NOTE 라라벨 5.1
1
$ php artisan make:controller ArticlesConroller
새로운 라우트를 정의할 텐데 그간 봐왔던 Route::get()이 아니라 Route::resource()를 쓴다는 점을 주목하자.
routes/web.php
1
Route::resource('articles', 'ArticlesController');
8.2.2 RESTfull 리소스 컨트롤러 개요
아지튼 명령어로 라우트를 확인해 본다
라우트 목록 확인
1
2
3
4
5
6
7
8
$ php artisan route:list
+--------+----------+----------+------+---------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------+------+---------+------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api |
| | | | | | auth:api |
+--------+----------+----------+------+---------+------------+
명칭 | 설명 |
---|---|
Domain | URL 경로뿐만 아니라 도메인에 따라 라우팅을 분리할 수 있다 |
Method | HTTP 요청 메서드 |
URI | 경로 |
Name | 라우트 이름 |
Action | 라우팅을 처리할 컨트롤라와 메서드 |
Middleware | 이 라우팅에 적용할 전역 또는 HTTP 미들웨어 |
REST 원칙에 맞춘 URL과 컨트롤러 메서드
HTTP메서드 | URL 경로 | HTTP 메서드 오버라이드 | 처리할 컨트롤러 | 설명 |
---|---|---|---|---|
GET | articles | ArticlesConroller@index | Article 모델 컬렉션 조회 | |
POST | articles | ArticlesConroller@store | 새 Article 모델 만들기 | |
GET | articels/create | ArticlesConroller | 새 Article 모델 프로퍼티 값을 입력 받기 위한 폼 | |
GET | articles/{article} | ArticlesConroller@show | {article} 기본키 값을 가진 Articel 모델 조회 | |
POST | articles/{article} | _method=PUT | ArticlesConroller@update | {article} 기본 키값을 가진 Article모델의 프로터티값을 수정 |
POST | articles/{article} | _method=DELETE | ArticlesConroller@destroy | {article} 기본 값을 가진 Article 모델 삭제 |
GET | articles/{article}/edit | ArticlesConroller@edit | {article} 기본 값을 가진 Article 모델 프로퍼티 수정값을 받기 위한 폼 |
8.2.3 RESTfull 리소스 컨트롤러 테스트
앞서 만든 ArticlesConroller를 수정한다 __METHOD__ 는 자신을 포함한 메서드 이름을 담고 있는 메직 상수다.
app/Http/Controllers/ArticlesController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ArticlesController extends Controller
{
public function index()
{
return __METHOD__."은 아티클 컬렉션을 조회합니다.";
}
public function create()
{
return __METHOD__."은 아티클 컬렉션을 만들기 위한 폼을 담은 뷰를 반환합니다.";
}
public function store(Request $request)
{
return __METHOD__."은 사용자릐 입력한 폼 데이터로 새로운 아티클 컬렉션을 만듭니다.";
}
public function show($id)
{
return __METHOD__."은 다음 기본 키를 가진 아티클 모델을 조회합니다.".$id;
}
public function edit($id)
{
return __METHOD__."은 다음 기본 키를 가진 아티클 모델을 수정하기 위한 폼을 담은 뷰를 반환합니다.".$id;
}
public function udpate(Request $request, $id)
{
return __METHOD__."은 사용자의 입력 폼 데이터로 다음 기본키를 가진 아티클 모델을 수정합니다.".$id;
}
public function destroy($id)
{
return __METHOD__."은 다음 기본 키를 가진 아티클 모델을 삭제합니다.".$id;
}
}
toubleshooting
라라벨 8버전 부터는 위 코드는 에러가 발생한다 /app/Providers/RouteServiceProvider.php
로 가서 29번라인에 protected $namespace = 'App\\Http\\Controllers';
주석을 해제하자
/artticle , /article/1 를 호출해 보자.
8.2.4 CSRF 공격 방어 기능
위 경로를 POST 형식으로 호출시 오류가 발생한다. 라라벨을 데이터를 변경하는 POST 동작에 대해서는 토큰을 요구한다. 이러한 보호 동작은 아래와 같다
- GET /article/create 요청에 ArticleController@create 메서드에서 숨은 필드로 _token 값을 담아 새로운 모델 만들기 폼(뷰)를 응답한다.
- 브라우저가 _token 필드를 HTTP 묘청 본문에 담아 POST articles 요청을 한다.
- POST /article 라우팅이 컨트롤러에게 작업을 할당하기 전에 web 미들웨어 그룹을 실행한다.
- 이 미들웨어 그룹에는 CSRF 토큰 검사가 포함되어 있는데, 폼을 응답했던 세션에서 만든 _token과 지금 HTTP 요청으로 받은 _token이 같은지 확인한다.
- CSRF 토큰 검사를 통화하면 ArticleController@store 메서드에게 작업을 위함하고, 그렇지 않으면 TokenMismatchException을 던진다.
우리는 테스트를 위해 위 기능을 잠시 끈다
app/Http/Middleware/VerifyCsrfToken.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
'articles',
'articles/*'
];
}
8.2.5 메소드 오버라이드
POST /article/1 요청시, 수정과 삭제 라우트를 구분하지 못해 MethodNotAllowedHttpException 가 발생한다. 원칙적으로는 수정은 PUT 또는 PATCH , 삭제는 DELETE 이지만 보안등을 이유로 비허용한 곳이 많다. 그런 경우, body에 _method를 키로 PUT을 값으로 전달하면 된다.
8.2.6 RESTful 라우트 보충
우리가 배운 메서드 외에도 다음과 같은 라우트 메서드가 있다.
Route::post(string $url , \Closure array string $action) Route::put(string $url , \Closure array string $action) Route::patch(string $url , \Closure array string $action) Route::delete(string $url , \Closure array string $action) Route::options(string $url , \Closure array string $action)
Comments powered by Disqus.