Url for API to login and get access token - laravel-5

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.

Related

Receive empty Array as output when request is sent

I created 2 classes called UserStoreRequest and UserAuthController in my laravel project. UserStoreRequest is a FormRequest to Validate the Request coming from the user. Once I send parameters, I just want to access these inside the Register method, but I get an empty array as response, instead of parameters sent.
UserAuthController:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\UserStoreRequest;
use App\Models\User;
class UserAuthController extends Controller
{
public function register(UserStoreRequest $request)
{
dd($request->all());
/* $data = $request->validate([
'name' => 'required|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|confirmed'
]);
$data['password'] = bcrypt($request->password);
$user = User::create($data);
$token = $user->createToken('API Token')->accessToken;
return response(['user' => $user, 'token' => $token]);*/
}
}
UserStoreRequest:
namespace App\Http\Requests;
use Illuminate\Http\Request;
class UserStoreRequest 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()
{
return [
//
];
}
}
Below I put the route used in the API class to send parameters:
Route::post('/register', 'App\Http\Controllers\Auth\UserAuthController#register');
It looks like you're trying to use a Form Request. To do so, make sure you extend the proper parent class.
// Incorrect
use Illuminate\Http\Request;
class UserStoreRequest extends Request { /* ... */ }
// Correct
use Illuminate\Foundation\Http\FormRequest;
class UserStoreRequest extends FormRequest { /* ... */ }
The Laravel dependency injection container is able to instantiate a new instance of your existing Request, which is why you don't receive any errors and an instance of your request is available to the controller. However, Laravel doesn't know to populate it with the actual request data. That's where FormRequest comes in.

How to use the ignore rule in Form Request Validation

this is PostsRequest.php in http/request:
<?php
namespace App\Http\Requests;
use App\Post;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class PostsRequest 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 [
'title' => ['required','max:255', Rule::unique('posts')->ignore($this->id)],
'slug' => ['required', Rule::unique('posts')->ignore($this->id),],
'content' => 'required',
'type' => 'required|in:blog,download,page',
'status' => 'required',
];
}
}
and this is edit() method in PostController.php
public function update(PostsRequest $request, $id)
{
$validated = $request->validated();
$validated['user_id'] = auth()->user()->id;
$post = Post::find($id)->fill($validated);
$post->save();
return redirect()->action('PostController#index');
}
Problem: show error in update page that this value is already exists.
who to resolve problem unique fields in edit form?
Problem Solved
change:
Rule::unique('posts')->ignore($this->route('id'))
with:
Rule::unique('posts')->ignore($this->route('post'))
If you're wanting to resolve the $id from the route then you can use the route() method in your request class e.g.
Rule::unique('posts')->ignore($this->route('id'))

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',
]);

NotFoundHttpException with my Request file on api route

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.

Add error to validation errors using formRequest

i'm trying to figure out how to add a error message to the default $error generated by the Illuminate\Support\MessageBag when using validation trough requests.
I've searched on google and the laravel docs and not really found information clarifying this for me.
AuthController
<?php
namespace App\Http\Controllers\Auth;
use Auth;
use App\User;
use App\Http\Requests\LoginFormRequest;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
/*
* AuthController
*/
class AuthController extends Controller {
/*
* Create view
*
* #return View
*/
public function getLogin() {
return view('auth.login');
}
/*
* Validate Login
*
* #return Redirect route
*/
public function postLogin(LoginFormRequest $request) {
if (Auth::attempt(array('email' => $request->email, 'password' => $request->password), $request->remember)) {
return redirect()->intended('home')->with('success-message', 'Succesfully authenticated');
} else {
$validator->addMessage('Incorrect email and password combination');
return redirect('account.login')->withErrors($validator)->withInput();
}
}
}
LoginFormRequest
<?php
namespace App\Http\Requests;
use Response;
use Illuminate\Foundation\Http\FormRequest;
class LoginFormRequest extends FormRequest {
public function rules() {
return array(
'email' => 'required|email',
'password' => 'required|between:8,20'
);
}
public function authorize() {
return true;
}
}
Hopefully someone has encountered this problem before and can help me!
Just add the messsages() function to your LoginFormRequest class:
public function messages()
{
return array(
'email.required' => 'The email address is required.',
'password.required' => 'The password is required.',
'password.between' => 'The password should be between 8 and 20 characters.',
);
}
Using the dot notation, you specify the field first and then the type of validator.
$validator->getMessageBag()->add("password", "Username and/or password don't match.");
Will add an error for this field.

Resources