NotFoundHttpException with my Request file on api route - laravel

I made a route in the api file that allow everybody to create users :
Route::post('users', 'UserController#addUser');
When I called it in postman without using request validation it works. But when I created my request file and use it, Laravel return a NotFoundHttpException.
Here's my request file :
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserAddRequest 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 [
'user_id' => 'required|numeric',
'name' => 'required|string',
'email' => 'required|string',
'password' => 'required|string'
];
}
}
public function addUser(UserAddRequest $request){
$user = new User;
$user->instance_user_id = $request->input('user_id');
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->password = $request->input('password');
$user->save();
}
There is no form because it needs to be send directly to the server with post method. I declared my route in routes/api.php and I call it with the url /api/users The api in that case doesn't need to check credentials.

I solved my problem :
The NotFoundHttpException was raised because I didn't send my parametters correctly and Laravel doesn't where to redirect me back. When I send directly the request to the server there is no url declared for where I'm coming.

Related

How to add errors after FormRequests validation?

How to add errors after FormRequests validation?
password_repository->update() will return an error if the current passwords entered do not match.
password_repository->update() calls an external API.
I want to add an error in the controller depending on the return value of the repository.
In PasswordRequest, validation after calling the external API cannot be described, so I am in trouble.
For this reason I want to add an error in the controller after doing password_repository->update().
PasswordController.php
public function completeEdit(PasswordRequest $request)
{
$input = $request->only(['password', 'new_password']);
$data = $this->password_repository->update($input);
//I want to add an error at this point!!!
return view('pages.password.edit.complete');
}
}
PasswordRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class PasswordRequest 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 [
'password' => 'required',
'new_password' => 'required|confirmed',
'new_password_confirmation' => 'required',
];
}
}
Redirect with errors could help you.
return redirect()->back()->withErrors([
'Password not correct',
]);
Or return to a specific route.
return redirect()->route('password.create')->withErrors([
'Password not correct',
]);

Url for API to login and get access token

I want to validate the email and password of someone connecting through an API.
The idea is that they login through POST to site.com/api/v1/token?email=foo#bar.com&password=foobar
I was reading that best practices should be to make a https://laravel.com/docs/7.x/validation#creating-form-requests to handle the validation, but I couldn't understand how to validate the $user, because when I created the new Class there wasn't any request there.
I'm not sure if I'm missing something.
I was able to do it through the Controller just checking if the user exists and the password is valid.
The app would ping this URL with email/password, then get a Token as a response with the $user information and use this token to post/edit/delete other data
First you have to create a FormRequest class by using artisan command:
php artisan make:request ApiLoginRequest
After artisan command, it will create a new file inside you app/Http/Request with name ApiLoginRequest.php.
Inside this file you have to define validation rules like this.
<?php
namespace App\Http\Request;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
class ApiLoginRequest 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(Request $request)
{
$rules = [
'email' => 'required|email|exists:users,email',
'password' => 'required'
];
return $rules;
}
/**
* #name messages
*
* #description
*/
public function messages() {
return [
'email.required' => 'Required',
'password.required' => 'Required',
'email.email' => 'Must be a valid email address',
'email.exists' => 'Email address not found'
];
}
}
Then after you have to use this Request class inside your controller.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Request\ApiLoginRequest;
class ApiLoginController extends Controller {
public function login ( ApiLoginRequest $request ){
$user = \App\User::where('email', $request->get('email'))->find();
if( \Hash::check( $user>password, $request->password ) ){
// Do Login processed
}else{
$data = [
'success' => false,
'message' => 'Password dows not match'
];
return response()->json( $data, 500);
}
}
}
Like this you can use FormRequest class and benefit of this FormRequest class you can reuse this validation rules and also your controller looks good.

Laravel 6 - How to Log All URL's of User Visited

I want to log all URL's that user visited. But there's not the url i want to logged from my code. Here are the code that im done, please give me some advise. Thanks and appreciate.
Web Routes
Route::get('/{url}', 'LogController#myTestAddToLog')->where('url', '[\w\d\-]+(.*)');
Log Controller
public function myTestAddToLog()
{
\LogActivity::addToLog('My Testing Add To Log.');
}
App/Helpers LogActivity
public static function addToLog($subject)
{
$log = [];
$log['url'] = Request::fullUrl();
$log['ip'] = Request::ip();
$log['user_id'] = auth()->check() ? auth()->user()->id : 1;
LogActivityModel::create($log);
}
You need to create a middleware.
php artisan make:middleware AddToLog
And then, put your code inside the middleware.
<?php
namespace App\Http\Middleware;
use Closure;
use App\LogActivityModel;
class AddToLog
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
if(auth()->user()) {
LogActivityModel::create([
'url' => request()->fullUrl(),
'ip' => request()->ip(),
'user_id' => auth()->id(),
]);
}
return $response;
}
}
Then, inside app/Http/kernel.php, add your middleware to $middleware. This would allow any URL called would trigger this code.
protected $middleware = [
...
\App\Http\Middleware\AddToLog::class,
];
For those who still has the issue I had modified a bit the answer provided by #Adlan and based on the comments of his answer. Since you will be logging the activities after the request has been performed, the accepted answer needs to be modified. Following is the modified code.
public function handle($request, Closure $next)
{
$response = $next($request);
if(auth()->user()) {
Activity::create([
'url' => request()->fullUrl(),
'ip_address' => request()->ip(),
'user_id' => auth()->id(),
]);
}
return $response;
}
First, the response for the next request is saved. Then user authentication is checked and finally, the response is returned.
Reference : https://laravel.com/docs/5.8/middleware
https://stackoverflow.com/a/59816949/7070809
Please use the below code to log all url that user has visited
Log::info(url()->full()); // For just loggin
And for storing user log create table store the url with timestamp and IP

Trying to reset Passwords in Lumen

I am trying to implement password reset feature in Lumen but could not succeed.
Lumen has access to things like Laravel's PasswordBroker and PasswordManager but I am not able to use this and succeed. Is there any solution for this.
I literally just figured this out last night and wrote a blog about it:
http://www.imjohnbon.com/password-resets-in-lumen/
Hopefully it can at least get you on the right track.
Ok, so I just got this working myself, with Lumen 5.6. (I've upgraded to 5.8, still works, no changes made).
These are the changes I had to make to my code. I had to tweak a few things to suit my system, but this might help someone else.
Routes
I wanted two routes.
Send reset password email
GET auth/resetpassword?email=fred#example.com
Reset Password
PUT auth/resetpassword?token=281...b&username=fred&password=banana&password_confirmation=banana
Composer
To send the user an email, the following Laravel packages are needed:
composer require illuminate/mail "^5.6"
composer require illuminate/notifications "^5.6"
Config files
Some extra config file are needed:
config/auth.php
config/mail.php
I just copied these over from Laravel 5.6, no changes made. I also added the mail variables into my .env file.
bootstrap/app.php
These new files need to be registered in the app:
$app->configure('auth');
$app->configure('mail');
$app->register(Illuminate\Notifications\NotificationServiceProvider::class);
$app->register(\Illuminate\Mail\MailServiceProvider::class);
$app->alias('mailer', \Illuminate\Contracts\Mail\Mailer::class);
$app->withFacades();
Database
I used the default Laravel password_resets table:
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
Now the real changes to the code.
Based on the code from Illuminate\Foundation\Auth\SendsPasswordResetEmails and Illuminate\Foundation\Auth\ResetsPasswords.
AuthController
use Illuminate\Auth\Passwords\PasswordBrokerManager;
use Illuminate\Support\Facades\Password;
use Laravel\Lumen\Routing\Controller;
use Illuminate\Http\Request;
class AuthController extends Controller
{
// 1. Send reset password email
public function generateResetToken(Request $request)
{
// Check email address is valid
$this->validate($request, ['email' => 'required|email']);
// Send password reset to the user with this email address
$response = $this->broker()->sendResetLink(
$request->only('email')
);
return $response == Password::RESET_LINK_SENT
? response()->json(true)
: response()->json(false);
}
// 2. Reset Password
public function resetPassword(Request $request)
{
// Check input is valid
$rules = [
'token' => 'required',
'username' => 'required|string',
'password' => 'required|confirmed|min:6',
];
$this->validate($request, $rules);
// Reset the password
$response = $this->broker()->reset(
$this->credentials($request),
function ($user, $password) {
$user->password = app('hash')->make($password);
$user->save();
}
);
return $response == Password::PASSWORD_RESET
? response()->json(true)
: response()->json(false);
}
/**
* Get the password reset credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(Request $request)
{
return $request->only('username', 'password', 'password_confirmation', 'token');
}
/**
* Get the broker to be used during password reset.
*
* #return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
$passwordBrokerManager = new PasswordBrokerManager(app());
return $passwordBrokerManager->broker();
}
}
User model
use Illuminate\Auth\Passwords\CanResetPassword as CanResetPasswordTrait;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordInterface;
use Illuminate\Notifications\Notifiable;
class User extends Model implements CanResetPasswordInterface
{
use CanResetPasswordTrait;
use Notifiable;
...
}

Validation fileds from ajax request [Laravel 5]

Here is my validation request :rules
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Support\Facades\Auth;
class UpdateCommentRequest extends Request {
/**
* 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() {
$user = Auth::user()->id;
return [
'comment' => 'required|between:15,600',
'projectID' => "required|exists:project_group,project_id,user_id,$user|numeric",
'order' => "required|numeric",
'level' => "required|numeric"
];
}
}
And in my model I have like this:
public function apiUpdateComment(UpdateCommentRequest $request){
$comment = Comment::find(Input::get("order"));
$comment->text = Input::get('comment');
if($comment->save()){
return 'success';
}
}
This fileds I need to validate agins rules array:
array(
'comment' => Input::get('comment'),
'projectID' => Input::get('projectID'),
'order' => Input::get("order"),
'level' => Input::get("level"),
);
I need to check if all rules are ok and then update comment... Anyone can help?
public function apiUpdateComment(UpdateCommentRequest $request){
$comment = Comment::find($request->get("order"));
$comment->text = $request->get('comment');
if($comment->save()){
return 'success';
}
}
The logic behind the code:
A post request is send the the server and the route file sends it the the apiUpdateComment with all variables inside the $request. But before the code of the function is executed the validator checks the rules in your UpdateCommentRequest. If the test fails it will return errors. If it pass a comment with the id will be updated.

Resources