How to handle oauth2 and csrf token laravel - php

I installed Laravel 5.2 and oAuth2 Server Laravel
in my project. I have to use same function for web-site and web-api. For web-site my function is working properly but when I use same function for web-api shown error TokenMismatchException in VerifyCsrfToken.php line 67:.
My Route
/* for web*/
Route::post('admin/user_login', 'Auth\AuthController#authenticate');
/* for mobile api */
Route::group(['prefix'=>'api/','before' => 'oauth'], function()
{
Route::post('/user/login', 'Auth\AuthController#authenticate');
});
When I use this controller for web, this code working fine but when I call API that time shown error. How I can handle this? I have to use oAuth route and web route parallel. Thanks in advance.

you have to disable csrfToken verification for routes starting with api to do that edit your app/Http/Middleware/VerifyCsrfToken.php file and add api/* in the $except array the sample file from laravel app repo is as below
https://github.com/laravel/laravel/blob/5.2/app/Http/Middleware/VerifyCsrfToken.php
just make it something like
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'api/*'
];
}
also you have to remove oauth middleware from authenticate route, because during authentication the token is not available so route goes something like below
Route::group(['prefix'=>'api/'], function()
{
Route::post('/user/login', 'Auth\AuthController#authenticate');
Route::group(['middleware' => 'oauth'], function() {
// routes which needs oauth token verification.
})
});

Related

Laravel CSRF protection exception now working

My Laravel project is in this link
http://localhost/demo/public // laravel project
and I have this external HTML form
http://localhost/attendance
Now I want to send data from the form to Laravel
but I got this error
419
Page Expired
so in my laravel project VerifyCsrfToken Class I wrote this
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'http://localhost/attendance'
];
}
but still, got the same error
419 Page Expired
Laravel resolve for you the baseUrl of your application, there is no need to put the full path, in your case the Middleware should be like below:
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'attendance/*'
];
}
One solution would be to send the data as a GET request instead of a POST one.
Once you put your work online, you would face cross-site protection on the browser.
The URI to be excluded is the one receiving the request so http://localhost/demo/public

Why does the Laravel API return a 419 status code on POST and PUT methods?

I am trying to create a RESTful API by using Laravel. I have created my controller using php artisan make:controller RestController and this is my controller code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class RestController extends Controller
{
private $arr = array(
array("name"=>"jon", "family"=>"doe"),
array("name"=>"jhon", "family" => "doue")
);
public function index(){
return json_encode($this->arr);
}
public function store(Request $request){
return "oops!!";
}
public function update (Request $request, $id){
return "test";
}
}
I have added this line of code to create this route in my routes/web.php file:
Route::resource('person', 'RestController');
When I try to test this api on GET /person it works fine but on POST and PUT I am getting a 419 status code from Laravel.
If you are developing REST APIs, you better not add tokens. If you are using 5.4 or 5.5 you can use api.php instead of web.php. In api.php you don't need token verification on post requests.
If you are using web.php, then you can exclude routes that you don't want to validate with CSRF Tokens.
Here is the official documentation:
Excluding URIs From CSRF Protection
Sometimes you may wish to exclude a set of URIs from CSRF protection. For example, if you are using Stripe to process payments and are utilizing their webhook system, you will need to exclude your Stripe webhook handler route from CSRF protection since Stripe will not know what CSRF token to send to your routes.
Typically, you should place these kinds of routes outside of the web middleware group that the RouteServiceProvider applies to all routes in the routes/web.php file. However, you may also exclude the routes by adding their URIs to the $except property of the VerifyCsrfToken middleware:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}
For reference https://laravel.com/docs/5.5/csrf
As per my Knowledge there are two methods to solve this
Method 1: Add CsrF Token
Method 2: Exclude URIs from CSRF protection
How to use
Method 1: Add one more variable to your POST request
_token: "{{ csrf_token() }}"
Example for Ajax
req = $.ajax({
type: "POST",
url: "/search",
data: {
"key": "value",
_token: "{{ csrf_token() }}",
},
dataType: "text",
success: function(msg) {
// ...
}
});
Example if you using forms
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
Method 2: There is a file named VerifyCsrfToken in following location
yourProjectDirectory/app/Http/Middleware
Add your URL in following method
protected $except = [
'url1/',
'url2/',
];
When To use
If you are the owner(full control) of API, use Method 1, as CSRF Token adds security to your application.
If you are unable to add CSRF Token like in case if you are using any third party API's, webhooks etc., then go for Method 2.
This can solve by excluding csrf protection of specific route you want to.
Inside your middleware folder, edit the file called VerifyCsrfToken.php
protected $except = [
'http://127.0.0.1:8000/person/'
];
I solved this problem by changing my server cache setting.
You can disable all of your caching systems (Nginx, Cloudflare, ...) to check it and then
turn it on by applying QueryString + Cookie to prevent caching a page with old csrf token in it.
I had the same issue when did POST requests to a Laravel API.
I solved the issue sending Accept: application/json in the headers request.

How to handle post request in Laravel app from another app?

I expect in Laravel 5.2 app post request from other system, when I handle it I receive:
TokenMismatchException in VerifyCsrfToken.php line 67:
Normally when I send post form I add in code {{ csrf_field() }}, but in this case request is from different app. So how to handle it without error?
You can add the URIs that should be excluded from verification to the $except property in the VerifyCsrfToken middleware.
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'api/*',
];
}
Documentation
You can exclude URI, to which reuqest from another application is send, from CSRF protection. This is described in doc here

laravel VerifyCsrfToken excepts url with wildcard?

I try to build my own API. I begin so my only model for the moment will be a "User". Here is how I would like to call my API :
HTTP/POST http://example.com/api/user/ # get all the users
HTTP/POST http://example.com/api/user/1 # get the user with id "1"
HTTP/POST http://example.com/api/user/1/delete # delete the user with id "1"
...
So my file routes/web.php looks like this :
<?php
Route::group(['prefix' => 'api'], function() {
Route::group(['prefix' => 'user'], function() {
Route::post('/', 'ApiController#allUsers');
});
});
?>
But it will not works as I do not pass throught Route::resource static method, but with regular Route::post method. So the issue is that VerifyCsrfToken middleware will trigger and try to check for my CSRF token, but as I want my api to be consume in the future by many other advice I prefer to use my own secure system (which will be a public-private key pairs, but now I just want to check for the integrity of the data I distribute through the api, and I will then set the secure algorithm).
The good news is that Laravel is so clean and let you add your exceptions URL in the VerifyCSRFToken array which is shaped like this :
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'api/user',
'api/user/{howCanIManageTheWildCard}',
'api/user/{howCanIManageTheWildCard}/delete',
...
];
}
?>
Question :
You see on the middleware above I have 2 issues :
I will have to set manually all my routes (which at the end can be long)
I do not know if the middleware will be able to handle any wildcard
So can I come with a solution wich could let me do a url wildcard like api/* ? Like this it would be so much easier !
You can exclude URLs with /*
Eg.
instead of api/user you can use api/user/*
read here
Just a suggestion
since you are building an API using laravel you can put all your API routes in api.php routes file instead of web.php routes file, In that case you will not have to pass CSRF Token for post request on API routes.
And all the API routes will be like example.com/api/<route> by default, you will not have to group it.
you can read more about Laravel routing here
happy to help :):):)
Sometimes we use simple URL or Sometimes URL/Route carries some value. so that type of situation you can use these two codes. change code in a file
App\Http\Middleware\VerifyCsrfToken.php and $except =[]
for simple Route
$except =['http://127.0.0.2/oams/public/oams/payment/success']
for dynamic Route
// http://127.0.0.2/oams/public/oams/payment/{RandCode}/success
$except =['http://127.0.0.2/oams/public/oams/payment/*']

How to have csrf token from mobile in Laravel Application

I am building a cordova application,
In the Login Authentication
From Web, I am sending the _token , email & password.
But From Mobile, I can't generate _token as it is basically a .html file.
I planned to do a request in the form document.ready to a controller which will generate _csrf token. So that i can use that token for that request.
But it can be watched from browser's Network Tab.
How can set the csrf _token to the form without others knowledge (safe way).
Or How it can be deal without any vulnerabilities
to disable csrf token for a specific url follow this.
First go to app/Http/Middleware/VerifyCsrfToken.php then use your url to avoid csrf token
protected $except = [
'my/url',
];
You can disable CSRF token checking in your laravel application for all routes. just open app/Http/Middleware/VerifyCsrfToken.php file and add '*' in $except array
Eg.
protected $except = [
'*'
];
my VerifyCsrfToken.php file
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'*'
];
}

Categories