30/09/2018, 21:14

[PHP - Laravel 5] Thắc mắc về Token

Chào mọi người, mấy nay không biết sao website của mình sau khi gởi form lên Server hay bị báo TokenMismatchException. Mình đã gắn token vào mỗi form rồi. Và nó hay bị lỗi với mấy form gởi bằng method POST.

<form action="example.com" method="post">
    <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
    <!-- TODO -->
</form>

Tại một form đó, có lúc mới vừa load trang xong là submit liền thì chạy bình thường. Lúc vừa load xong, submit là bị dính TokenMismatch liền. Mong mọi người giúp đỡ.

cpt viết 23:27 ngày 30/09/2018

Mình nghĩ do lúc load trang và lúc submit là 2 request khác nhau nên mới TokenMismatch

Võ Hoài Nam viết 23:17 ngày 30/09/2018

Mình đã kiểm tra Token của trang và Token của form. Nó đều giống như nhau cả.

Sáng Béo viết 23:28 ngày 30/09/2018

các routes đã cùng middleware => web chưa ạ? (Laravel 5.2 trở lên)

Nam viết 23:26 ngày 30/09/2018

hôm bữa cũng mò mãi, sau mới nhìn lại nó nằm ngoài middleware web

Võ Hoài Nam viết 23:24 ngày 30/09/2018

Bạn có thể nói rõ hơn hoặc cho mình xin đường link tới vấn đề đó được không?

Đinh Quốc Hân viết 23:14 ngày 30/09/2018

các routes đã cùng middleware => web chưa ạ? (Laravel 5.2 trở lên)

Sai rồi, từ laravel 5.2 trở đi mọi router mặc định sẽ chuyển sang web trừ các router API.

Bạn có thể nói rõ hơn hoặc cho mình xin đường link tới vấn đề đó được không?

Anh đang dùng Laravel phiên bản bao nhiêu nếu dưới 5.2 thì vào app\Http\routes.php chỉnh các Router middleware về web:

Route::get('/', ['middleware' => ['web'], 'uses' => 'MainController@index']);

hoặc sử dụng Router::group

Route::group(['middleware' => ['web']], function () {
    ... Router ở đây
    Route::get('/', 'HomeController@index');
});

Hoặc dùng thử chuyển cái form token xem nếu ở Laravel 5.2:

<form action="example.com" method="post">
    <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
    <!-- TODO -->
</form>

thành

<form action="example.com" method="post">
    {!! csrf_field() !!}
    <!-- TODO -->
</form>
Đinh Quốc Hân viết 23:18 ngày 30/09/2018

các routes đã cùng middleware => web chưa ạ? (Laravel 5.2 trở lên)

Lý do sai là ở đây, trong RouterServiceProvider của phiên bản 5.2 trở lên có đoạn này đã mặc định middlware web cho tất cả Router:

class RouteServiceProvider extends ServiceProvider
{
    ...
    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @param  \Illuminate\Routing\Router  $router
     * @return void
     */
    protected function mapWebRoutes(Router $router)
    {
        $router->group([
            'namespace' => $this->namespace, 'middleware' => 'web',
        ], function ($router) {
            require app_path('Http/routes.php');
        });
    }
}
Sáng Béo viết 23:15 ngày 30/09/2018

trước mình làm thì đã là bản 5.2 rồi. và mình cũng bị lỗi thế kia và lỗi Session nữa nếu không cho mấy router vào middleware web.
mặc định hay không mình không rõ nhưng mình phải thêm vào nó mới chạy được TT_TT

Đinh Quốc Hân viết 23:19 ngày 30/09/2018

tớ ko biết bạn có nhầm không nhưng changelog version 5.2 là thế

À chắc bạn dùng 5.2.0 rồi, cái này là bản fix từ 5.2.x trở đi mới có

Sáng Béo viết 23:29 ngày 30/09/2018

À chắc bạn dùng 5.2.0 rồi, cái này là bản fix từ 5.2.x trở đi mới có

đúng r, lúc mình mới học là 5.2.0.

Nam viết 23:15 ngày 30/09/2018

Thử view-source xem thằng này có giá trị không
csrf_token();

Võ Hoài Nam viết 23:19 ngày 30/09/2018

Chào mấy bác, nào giờ em xuất thì token nó ở những chỗ khai như phía dưới đều ra token trùng với trên thẻ <meta> của em.

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

Em có sử dụng cách của @dqh đề nghị là dùng

<form action="example.com" method="post">
    {!! csrf_field() !!}
    <!-- TODO -->
</form>

thay cho

<form action="example.com" method="post">
    <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
    <!-- TODO -->
</form>

Kết quả là em thấy 2 thằng này xuất ra đều như nhau. Nhưng hiện tại là chưa thấy em nó báo lỗi TokenMismatch nữa. Không biết sắp tới nó có báo hay không?

Em đang sử dụng Laravel 5.2.29.

Nếu bạn nào biết chỗ nào chỉnh lại timeout của Token thì cho mình biết với nhé. Tại thấy có chỗ khai báo 2 giờ nhưng mình treo khoảng 5 phút là bị dính TokenMismatchException.

Đinh Quốc Hân viết 23:16 ngày 30/09/2018

Nếu đã có token mà vẫn lỗi thì hơi lạ, anh dùng nó như thế nào nếu dùng dạng API AJAX là khác nữa nha anh.

Võ Hoài Nam viết 23:15 ngày 30/09/2018

Anh đang ở đường dẫn GET: /create. Sau đó, gởi một file Excel tới đường dẫn POST: /create để nhập sản phẩm bằng file Excel đó .

Không biết làm như vậy nó có bị lỗi không?

Đinh Quốc Hân viết 23:20 ngày 30/09/2018

Form anh có để dạng method="post" enctype="multipart/form-data". Lỗi này thường thì sẽ ko có xảy ra trừ khi session của php có vấn đề,

Võ Hoài Nam viết 23:29 ngày 30/09/2018

Anh sử dụng Cookie để lưu thông tin khi đăng nhập. Giả sử như em nói session của PHP có vấn đề. Anh nghĩ trường hợp xảy ra là trong khoảng thời gian ngắn (chưa tới 120 phút) thằng Session nó tự động đổi Token.

Ở file /config/session.php anh vẫn để cấu hình mặc định.

'lifetime' => 120,

'expire_on_close' => false,
Đinh Quốc Hân viết 23:28 ngày 30/09/2018

em mới thử build laravel 5.2 lại và cũng ko gặp lỗi như trên lỗi nằm ở đâu ta ???

Võ Hoài Nam viết 23:22 ngày 30/09/2018

Chắc anh bắt TokenMismatchException lại. Mỗi lần nó văng exception thì anh xài return redirect()->back() quá

Dù lỗi nhưng vẫn phải đảm bảo không ảnh hưởng tới quy trình nghiệp vụ của người ta, có thể họ chịu khó up lại lần nữa (chọn 1 file và điền 2 textbox). Anh nghĩ vậy.

Đinh Quốc Hân viết 23:21 ngày 30/09/2018

Anh dùng environment từ XAMPP hay Homestead ?

Võ Hoài Nam viết 23:16 ngày 30/09/2018

Ở local là VertrigoServ, ở host chạy Debian. Anh chỉ biết nhiêu đây thông tin à

Bài liên quan
0