in VerifyCsrfToken class i want to use for example
protected $except = [
'/dashboard/administrator/attachImage',
'/{ANY}/product/payment/checkTransaction'
];
instead of:
protected $except = [
'/dashboard/administrator/attachImage',
'/fa/product/payment/checkTransaction',
'/en/product/payment/checkTransaction',
'/ru/product/payment/checkTransaction',
'/az/product/payment/checkTransaction',
];
how can i use that and my question is laravel cab be support using regular expression on this array?
You can't use a regular expression, but since Laravel uses request's is() method under the hood, you can use asterisk like this:
protected $except = [
'/dashboard/administrator/attachImage',
'/*/product/payment/checkTransaction',
];
Related
Fortify has requireUppercase rule, but no requireLowercase, is it possible to somehow still have a rule that forces lower case in the password?
*Edit: Is it ok to use Laravel's password rule object instead of Fortify's one in PasswordValidationRules.php?
use Illuminate\Validation\Rules\Password; instead of use Laravel\Fortify\Rules\Password;
and then use it:
// app/Actions/Fortify/PasswordValidationRules.php
protected function passwordRules()
{
return [Password::min(8)->mixedCase()];
}
Or that might cause issues?
These are the methods that the Password object includes, you can skip some and add news:
Example:
$request->validate([
'password' => [
'required',
Password::min(12)
->letters()
->numbers()
->symbols(),
],
]);
Require at least 8 characters...
Password::min(8)
Require at least one letter...
Password::min(8)->letters()
Require at least one uppercase and one lowercase letter...
Password::min(8)->mixedCase()
Require at least one number...
Password::min(8)->numbers()
Require at least one symbol...
Password::min(8)->symbols()
You can use either Password class. The way the classes are used here is for nothing but validation, so there shouldn't be any lingering effects.
They will give you slightly different error messaging. The big difference (as you mentioned) is that the Fortify version doesn't have a requireLowercase() method.
Still, here are full examples of using each in PasswordValidationRules.php
Using the Fortify Password class.
<?php
namespace App\Actions\Fortify;
use Laravel\Fortify\Rules\Password;
trait PasswordValidationRules
{
/**
* Get the validation rules used to validate passwords.
*
* #return array
*/
protected function passwordRules()
{
return [
'required',
'string',
(new Password())
->requireUppercase()
->requireNumeric()
->requireSpecialCharacter(),
'confirmed',
];
}
}
and here is an example using the Illuminate\Validation\Rules\Password class.
<?php
namespace App\Actions\Fortify;
use Illuminate\Validation\Rules\Password;
trait PasswordValidationRules
{
/**
* Get the validation rules used to validate passwords.
*
* #return array
*/
protected function passwordRules()
{
return [
'required',
'string',
Password::min(8)
->mixedCase()
->numbers()
->symbols(),
'confirmed',
];
}
}
You could also create a class that extends Fortify's Password Class and add a requireLowercase method in nearly the same manner that requireUppercase is implemented.
I have a route which has a dynamic parameter at the end of the URL. In this route, I fetch data which is sent from an external API with the post method. As 419 page expired error occurs when the external API sends post request, I need to disable csrf protection for this route.
Related route:
Route::group(['middleware' => ['auth:student']], function (){
Route::post('Result', 'ExamController#Result')->name('exam.Result');
}
My URL example:
http://localhost.dev/student/Result?Id=N7utfGkwOLebxMWGA5iUC4S23jgRzW
I tried to add this code in VerifyCsrfToken file at App\Http\Middleware:
protected $except = [
'student/Result/*',
];
It doesn't work. But when I try student/*, it works perfectly. However, disabling the csrf protection for all student path is not what I want.
I tried also this way by getting reference on this thread:
Route::post('Result', [
'uses' => 'ExamController#Result',
'nocsrf' => 'true'
])->name('exam.Result');
That didn't work either.
How can I disable csrf protection in this scenario?
You made a typo at App\Http\Middleware, instead of:
protected $except = [
'student/Result/*',
];
You need to use:
protected $except = [
'student/Result',
];
Also, based on documentation you can specify the full url that need to be excepted:
protected $except = [
'http://localhost.dev/student/Result',
];
Be aware, that you don't need to add parameters part (everything after ? sign, e.g. ?Id=N7utfGkwOLebxMWGA5iUC4S23jgRzW) of route here.
Try this one (remove the slash and asterisk):
protected $except = [
'student/Result',
];
Is it possible to use abstract classes or interfaces in laravel Policies (Gates)? Like this:
protected $policies = [
MyAbstractClass::class => PostPolicy::class,
MyInterface::class => PostPolicy::class,
];
protected $policies = [
AbstractClass::class => ConcreteClass::class,
PostAbstractClass::class => PostConcreteClass::class,
];
It looks like the source code for Illuminate\Auth\Access\Gate falls back to is_subclass_of() when resolving a Policy instance. From the php docs for is_subclass_of():
Checks if the given object has the class class_name as one of its
parents or implements it.
(emphasis mine)
So yes, you should be able to do that.
there is a route like:
Route::post('user/{id}/update','UserController#update');
I want to disable csrf protection for it, but i don't know how to add its uri into except array.
You can add the given code in VerifyCsrfToken file at App/Http/Middleware
protected $except = [
'user/*',
];
or you can disable it on route file
Route::post('user/{id}/update', [
'uses' => 'UserController#update',
'nocsrf' => true,
]);
One of the best solution in recents versions of Laravel is using the withoutMiddleware method:
Route::post('user/{id}/update', 'UserController#update')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
This works even if you have the route inside a middleware group.
Route::middleware(['web'])->group(function () {
Route::post('user/{id}/update', 'UserController#update')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
});
I have URLs that look like:
http://example.com/api/user?id=45&name=mike&api_token=2348283
http://example.com/api/project?id=5&description=first&api_token=2348283
etc...
In my controllers, I have functions that look like:
public function user_get_endpoint(Request $request){
$request = $request->toArray();
return UserModel::where($request)->get()->toArray();
}
The above will currently break since the $request object contains a property called api_token which does not exist in the user table. I am using the api_token in a middleware to check for authentication.
I can manually unset the api_token property in each of my API functions by using unset($request['api_token'], but I'd like to avoid that if possible.
Is there anyway to do this application wide or at a class or controller level?
Laravel provides add and remove functions to add and remove new properties to the request object respectively.
$request->request->add(['api_token' => 'api_token']); // to add new property to $request
$request->request->remove('api_token'); // to remove property from $request
Perhaps you want global middleware?
First arrange for the middleware to run on all routes:
// routes.php
$app->middleware([
App\Http\Middleware\Apitoken::class
]);
Then define what the middleware should do:
// src/App/Http/Middleware/Apitoken.php
<?php
namespace App\Http\Middleware;
use Closure;
class Apitoken
{
public function handle($request, Closure $next)
{
unset($request['api_token']);
return $next($request);
}
}
Method 1
$request->except(['key1','key2',....])
provides an easy way to skip unwanted keys, similarly
Method 2
$request->only(['key3','key4',....])
provides an easy way to skip all others unwanted keys, I find both reasonably good for almost all scenarios
A solution that works for all HTTP Methods (not only for GET and HEAD) :
$except = ['api_token'];
$request = request();
$cleanup = $request->except($except);
$request->query = new \Symfony\Component\HttpFoundation\ParameterBag($cleanup);
Ideally, you should send your api_token in request headers instead of Uri params.
If you are using Laravel's auth:api Middleware for authentication then you can send api_token in headers as:
$response = $client->request('GET', '/api/user', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
],
]);
Then api_token will never come in your Uri params.
As #JanWillem said in the comments you can use except() which will remove the params you pass to it:
public function user_get_endpoint(Request $request){
return UserModel::where($request->except('api_token'))->get();
}
https://laravel.com/docs/5.2/requests#retrieving-input and then scroll down to Retrieving A Portion Of The Input Data
Furthermore, you don't have to use toArray() with the response as Laravel will automatically do this for you.
Hope this helps!