public function store(Request $request) {
$response = array('response' => '', 'success'=>false);
$rules = [
'email' => 'required|email',
'password' => 'required'
];
$validator = \Validator::make($request->all(), $rules);
if($validator->fails()){
$response['response'] = $validator->messages();
return $this->response->error($response, 401);
// or
return $this->response->error($validator, 401);
}else{
User::create($request->all());
}
}
How can I set validator in laravel using dingo API? I tried above code but does not work can't understand where is the right reference to keep track error logs
Please guide.
$rules = [
'username' => 'required',
'password' => 'required'
];
$payload = app('request')->only('username', 'password');
$validator = app('validator')->make($payload, $rules);
if ($validator->fails()) {
throw new Dingo\Api\Exception\StoreResourceFailedException('Invalid username provided.', $validator->errors());
}
You can try this
public function store()
{
$rules = [
'email' => 'required|email',
'password' => 'required'
];
$payload = app('request')->only('username', 'password');
$validator = app('validator')->make($payload, $rules);
if ($validator->fails()) {
throw new Dingo\Api\Exception\StoreResourceFailedException('Could not create new user.', $validator->errors());
}
User::create($request->all());
// send a success response
}
This example is taken from the documentation of Dingo and customized based on your code.
The best way I've found to do validation especially when using Dingo API is to use Form Requests.
When using Dingo API however, you use
use Dingo\Api\Http\FormRequest;
instead of
use App\Http\Requests\Request;
like in normal form requests.
So in your case, you'd have a form request like
<?php
namespace App\Http\Requests;
use Dingo\Api\Http\FormRequest;
class CreateUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'email' => 'required|email',
'password' => 'required'
];
}
}
So this keeps validations outside your controller. And your controller function can just be
public function store(Request $request) {
User::create($request->all());
}
If you are not very familiar with Form Requests, this is a great chance to look at it. Cheers.
Related
I'm using laravel 7
I have a Request that I've built but the required rule is not working. Request sends back without any error.
and dd() also not showing request data.
Function:
public function store(StoreRequest $request)
{
dd($request->all());
if (!auth()->user()->can('add-users')) {
abort(401);
}
try {
$userStatus = app(CreateUser::class)->execute($request->all());
if ($userStatus == true) {
return redirect()->back()->with('success', 'User successfully created.');
} else {
return redirect()->back()->with('error', 'Oops Something went wrong!');
}
} catch (\Exception $ex) {
return redirect()->back()->with('error', $ex->getMessage());
}
}
Request Code:
class StoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => ['required','string','max:255'],
'email' => ['required','string','max:255'],
'password' => 'required',
'organization_id' => 'required'
];
}
}
If I use Illuminate\Http\Request showing the request data but not validating the data.
Any idea?
Please can you try this
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|string|max:255',
'password' => 'required',
'organization_id' => 'required'
];
}
I'm using Laravel Sanctum in my Laravel 8 project, I'm building a controller which will allow other Laravel projects to authenticate and check the abilities of a token, to do this I'm finding a token using the findToken method, grabbing the tokenable_id (this is the user id) and then looking up this user based on the User model.
I'm then storing this in a variable and checking the abilities with tokenCan but it's always returning false despite my token having the correct abilities, what am I missing from this method?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Laravel\Sanctum\PersonalAccessToken;
use App\Models\User;
class HubController extends Controller
{
/**
* Instantiate a new AccountController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('throttle:30,1');
}
/**
* Handle the incoming request.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
$validator = Validator::make($request->all(), [
'token' => 'required|string',
'ability' => 'required|string'
]);
if ($validator->fails()) {
return response()->json([
'message' => "It looks like you've missed something.",
'errors' => $validator->messages()
], 400);
}
$token = PersonalAccessToken::findToken($request->input('token'));
if (!$token) {
return response()->json([
'message' => "Token not found or is invalid"
], 404);
}
$user = User::find($token->tokenable_id);
if (!$user) {
return response()->json([
'message' => "User not found or is invalid"
], 404);
}
// $user->tokenCan('reports:view') always returning false
return response()->json([
'token' => $user->tokenCan('reports:view'),
'message' => "You don't have the correct permissions to perform this action."
], 401);
return response()->json([
'user' => $user
], 200);
}
}
you can get $user with $request->user().
or use $request->user()->tokenCan('reports:view')
I was using Laravel's built-in api token authentication before but I wanted to provide multiple api tokens for different clients and with Laravel 7.x, I'm trying to migrate to Laravel Sanctum.
API seems authenticates user without any problem but when I try to get user data with Auth::user();, it returns null. Also Auth::guard('api')->user(); returns null too.
What should I use as Auth guard? Or is it correct way to get user data based on provided token?
Thank you very much....
auth('sanctum')->user()->id
auth('sanctum')->check()
without middleware, you could use these.
First, route through the sanctum auth middleware.
Route::get('/somepage', 'SomeController#MyMethod')->middleware('auth:sanctum');
Then, get the user.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function MyMethod(Request $request) {
return $request->user();
}
}
auth()->user() is a global helper, Auth::user() is a support facade, and $request->user() uses http. You can use any of them.
For a quick test, try
Route::get('/test', function() {
return auth()->user();
})->middleware('auth:sanctum');
Be sure to send your token in a header like so:
Authorization: Bearer UserTokenHere
Send token in the Authorization header, below code return the auth user.
Route::middleware('auth:sanctum')->group(function () {
Route::get('/profile/me', function (Request $request) {
return $request->user();
});
});
In case of restful api, suggest you to send Accept header also for checking at authenticate middleware for redirection if not authenticated. By default for restful api it redirect to login form (if any) if user not authenticated.
namespace App\Http\Middleware;
protected function redirectTo($request)
{
if (!$request->expectsJson()) {
return route('login');
}
}
When you are logging in the user, in your login function use something like this
public function login(Request $request)
{
if(Auth::attempt($credentials))
{
$userid = auth()->user()->id;
}
}
Then send this user id to the client and let it store in a secured way on client-side. Then with every request, you can use this user-id to serve data for next requests.
private $status_code= 200; // successfully
public function register(Request $request)
{
// $validator = $this->validator($request->all())->validate();
$validator = Validator::make($request->all(),
[
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255'], // , 'unique:users'
'password' => ['required', 'string', 'min:4'],
]
);
if($validator->fails()) {
return response()->json(["status" => "failed", "message" => "Please Input Valid Data", "errors" => $validator->errors()]);
}
$user_status = User::where("email", $request->email)->first();
if(!is_null($user_status)) {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! email already registered"]);
}
$user = $this->create($request->all());
if(!is_null($user)) {
$this->guard()->login($user);
return response()->json(["status" => $this->status_code, "success" => true, "message" => "Registration completed successfully", "data" => $user]);
}else {
return response()->json(["status" => "failed", "success" => false, "message" => "Failed to register"]);
}
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:4'],
]);
}
/**
* Create a new user instance after a valid registration.
* #author Mohammad Ali Abdullah ..
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
protected function guard()
{
return Auth::guard();
}
/**
* method public
* #author Mohammad Ali Abdullah
* #date 01-01-2021.
*/
public function login(Request $request)
{
$validator = Validator::make($request->all(),
[
"email" => "required|email",
"password" => "required"
]
);
// check validation email and password ..
if($validator->fails()) {
return response()->json(["status" => "failed", "validation_error" => $validator->errors()]);
}
// check user email validation ..
$email_status = User::where("email", $request->email)->first();
if(!is_null($email_status)) {
// check user password validation ..
// ---- first try -----
// $password_status = User::where("email", $request->email)->where("password", Hash::check($request->password))->first();
// if password is correct ..
// ---- first try -----
// if(!is_null($password_status)) {
if(Hash::check($request->password, $email_status->password)) {
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed ..
$authuser = auth()->user();
return response()->json(["status" => $this->status_code, "success" => true, "message" => "You have logged in successfully", "data" => $authuser]);
}
}else {
return response()->json(["status" => "failed", "success" => false, "message" => "Unable to login. Incorrect password."]);
}
}else{
return response()->json(["status" => "failed", "success" => false, "message" => "Email doesnt exist."]);
}
}
public function logout()
{
Auth::logout();
return response()->json(['message' => 'Logged Out'], 200);
}
I see that no answer has been accepted yet. I just had the problem that my sacntum auth did not work. The auth() helper always returned null.
To solve the problem I removed the comment in the kernel.php under the api key. It is about this class \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class. This is because it is commented out by default.
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
After that I had access to the User object with the auth() helper.
The simplest way to to that is to use auth helpers like
$user = auth('sanctum')->user();
Or you can get it by the request object
//SomeController.php
public function exampleMethod(Request $request)
{
$user = $request->user();
}
To get user by sactum token string like
2|bTNlKViqCkCsOJOXWbtNASDKF7SyHwzHOPLNH
Code be like
use Laravel\Sanctum\PersonalAccessToken;
//...
$token = PersonalAccessToken::findToken($sactumToken);
$user = $token->tokenable;
Note: The most way to pass token is from Authorization headers by bearer
Make sure the sanctum middleware is in api
I was in the same boat; migrated to Sanctum and wondered why all of my $request->user() were empty. The solution for me was to throw some middleware onto the stack to modify the request's user() resolver:
namespace App\Http\Middleware;
use Illuminate\Http\Request;
class PromoteSanctumUser
{
/**
* #param Request $request
* #param \Closure $next
*/
public function handle(Request $request, \Closure $next)
{
$sanctumUser = auth('sanctum')->user();
if ($sanctumUser) {
$request->setUserResolver(function() use ($sanctumUser) {
return $sanctumUser;
});
}
return $next($request);
}
}
Laravel 5.5
public function register(Request $request) {
request()->validate([
'email' => 'required:email'
'password' => 'required|min:6'
]);
return response()->json(["message" => "Hello World"]);
}
If validator is fails, not giving error messages. Redirecting main page.
If the code you're using redirects you to the previous page when validation fails, it means that you didn't tell the server what kind of response you want to receive.
Set a proper header to get JSON. It will make the validator send JSON in response. For example:
$.ajax({
headers: {
Accept : "application/json"
},
...
});
Then this code will work as expected:
public function register(Request $request)
{
$request->validate([
'email' => 'required:email'
'password' => 'required|min:6'
]);
return response()->json(["message" => "Hello World"]);
}
I had the same problem when testing my rest api in Postman application.
if we don't want to modify our current code of laravel redirect repose, we have to put Accept:-application/json and ContentType:-application/json
For modifying code in controller class file, i did it like this and got the json response instead of redirecting to home page.
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return response()->json($validator->errors());
} else {
// do something
}
}
before it looks like below codes it was redirecting to home page
This is validator function
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6',
]);
}
public function register(Request $request)
{
// Here the request is validated. The validator method is located
// inside the RegisterController, and makes sure the name, email
// password and password_confirmation fields are required.
$this->validator($request->all())->validate();
// A Registered event is created and will trigger any relevant
// observers, such as sending a confirmation email or any
// code that needs to be run as soon as the user is created.
event(new Registered($user = $this->create($request->all())));
// After the user is created, he's logged in.
$this->guard()->login($user);
// And finally this is the hook that we want. If there is no
// registered() method or it returns null, redirect him to
// some other URL. In our case, we just need to implement
// that method to return the correct response.
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
You can do this like this :
$validator = Validator::make($request->all(), [
'email' => 'required|email', //use pipe here to apply multiple validations rules and add a ','
'password' => 'required|min:6'
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()]);
}
return response()->json(["message" => "Hello World"]);
The validation is working well, but, $request->validate() will redirect you to the previous page. I recommend you to manually create your validations:
Manually Creating Validations.
You could do something like this:
use Illuminate\Http\Request;
use Validator;
class YourClass extends Controller{
public function yourFunction(Request $request) {
$validator = Validator::make($request->all(),[
'field_1' => 'rule1|rule2',
'field_2' => 'rule1|rule2'
]);
if ($validator->fails()) {
return response()->json($validator->errors());
} else {
/*Something else*/
}
}
}
try this, hope this code can help you
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
I'm trying to create customized messages for validation in Laravel 5. Here is what I have tried so far:
$messages = [
'required' => 'Harap bagian :attribute di isi.',
'unique' => ':attribute sudah digunakan',
];
$validator = Validator::make($request->all(), [
'username' => array('required','unique:Userlogin,username'),
'password' => 'required',
'email' => array('required','unique:Userlogin,email'),$messages
]);
if ($validator->fails()) {
return redirect('/')
->withErrors($validator) // send back all errors to the login form
->withInput();
} else {
return redirect('/')
->with('status', 'Kami sudah mengirimkan email, silahkan di konfirmasi');
}
But it's not working. The message is still the same as the default one. How can I fix this, so that I can use my custom messages?
Laravel 5.7.*
Also You can try something like this. For me is the easiest way to make custom messages in methods when you want to validate requests:
public function store()
{
request()->validate([
'file' => 'required',
'type' => 'required'
],
[
'file.required' => 'You have to choose the file!',
'type.required' => 'You have to choose type of the file!'
]);
}
If you use $this->validate() simplest one, then you should write code something like this..
$rules = [
'name' => 'required',
'email' => 'required|email',
'message' => 'required|max:250',
];
$customMessages = [
'required' => 'The :attribute field is required.'
];
$this->validate($request, $rules, $customMessages);
You can provide custom message like :
$rules = array(
'URL' => 'required|url'
);
$messages = array(
'URL.required' => 'URL is required.'
);
$validator = Validator::make( $request->all(), $rules, $messages );
if ( $validator->fails() )
{
return [
'success' => 0,
'message' => $validator->errors()->first()
];
}
or
The way you have tried, you missed Validator::replacer(), to replace the :variable
Validator::replacer('custom_validation_rule', function($message, $attribute, $rule, $parameters){
return str_replace(':foo', $parameters[0], $message);
});
You can read more from here and replacer from here
For Laravel 8.x, 7.x, 6.x
With the custom rule defined, you might use it in your controller validation like so :
$validatedData = $request->validate([
'f_name' => 'required|min:8',
'l_name' => 'required',
],
[
'f_name.required'=> 'Your First Name is Required', // custom message
'f_name.min'=> 'First Name Should be Minimum of 8 Character', // custom message
'l_name.required'=> 'Your Last Name is Required' // custom message
]
);
For localization you can use :
['f_name.required'=> trans('user.your first name is required'],
Hope this helps...
$rules = [
'username' => 'required,unique:Userlogin,username',
'password' => 'required',
'email' => 'required,unique:Userlogin,email'
];
$messages = [
'required' => 'The :attribute field is required.',
'unique' => ':attribute is already used'
];
$request->validate($rules,$messages);
//only if validation success code below will be executed
//Here is the shortest way of doing it.
$request->validate([
'username' => 'required|unique:Userlogin,username',
'password' => 'required',
'email' => 'required|unique:Userlogin,email'
],
[
'required' => 'The :attribute field is required.',
'unique' => ':attribute is already used'
]);
//The code below will be executed only if validation is correct.
run below command to create a custom rule on Laravel
ı assuming that name is CustomRule
php artisan make:rule CustomRule
and as a result, the command was created such as PHP code
if required keyword hasn't on Rules,That rule will not work
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class CustomRule implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
//return true or false
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The validation error message.';
}
}
and came time using that
first, we should create a request class if we have not
php artisan make:request CustomRequest
CustomRequest.php
<?php
namespace App\Http\Requests\Payment;
use App\Rules\CustomRule;
use Illuminate\Foundation\Http\FormRequest;
class CustomRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules(): array
{
return [
'custom' => ['required', new CustomRule()],
];
}
/**
* #return array|string[]
*/
public function messages(): array
{
return [
'custom.required' => ':attribute can not be empty.',
];
}
}
and on your controller, you should inject custom requests to the controller
your controller method
class FooController
{
public function bar(CustomRequest $request)
{
}
}
You can also use the methods setAttributeNames() and setCustomMessages(),
like this:
$validation = Validator::make($this->input, static::$rules);
$attributeNames = array(
'email' => 'E-mail',
'password' => 'Password'
);
$messages = [
'email.exists' => 'No user was found with this e-mail address'
];
$validation->setAttributeNames($attributeNames);
$validation->setCustomMessages($messages);
For those who didn't get this issue resolve (tested on Laravel 8.x):
$validated = Validator::make($request->all(),[
'code' => 'required|numeric'
],
[
'code.required'=> 'Code is Required', // custom message
'code.numeric'=> 'Code must be Number', // custom message
]
);
//Check the validation
if ($validated->fails())
{
return $validated->errors();
}
$rules = [
'name' => 'required',
'email' => 'required|email',
'message' => 'required|max:250',
];
$customMessages = [
'required' => 'The :attribute field is required.',
'max' => 'The :attribute field is may not be greater than :max.'
];
$this->validate($request, $rules, $customMessages);
In the case you are using Request as a separate file:
public function rules()
{
return [
'preparation_method' => 'required|string',
];
}
public function messages()
{
return [
'preparation_method.required' => 'Description is required',
];
}
Tested out in Laravel 6+
you can customise the message for different scenarios based on the request.
Just return a different message with a conditional.
<?php
namespace App\Rules;
use App\Helpers\QueryBuilderHelper;
use App\Models\Product;
use Illuminate\Contracts\Validation\Rule;
class ProductIsUnique implements Rule
{
private array $attributes;
private bool $hasAttributes;
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct(array $attributes)
{
$this->attributes = $attributes;
$this->hasAttributes = true;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
$brandAttributeOptions = collect($this->attributes['relationships']['brand-attribute-options']['data'])->pluck('id');
$query = Product::query();
$query->when($brandAttributeOptions->isEmpty(), function ($query) use ($value) {
$query->where('name', $value);
$this->hasAttributes = false;
});
return !$query->exists();
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return ($this->hasAttributes) ? 'The Selected attributes & Product Name are not unique' : 'Product Name is not unique';
}
}
Laravel 10.x
If you are using Form Requests, add another method called messages(): array in your request.
class YourRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => 'required',
'email' => 'required|email',
...
];
}
//Add the following method
public function messages(): array
{
return [
'email.required' => 'Custom message for Email Required',
];
}
}
Then the message will be displayed automatically once the request is send from the form.