I want to make a jwt api with laravel and angular , but i have a problem ; when i send my signup data to my laravel server it say's :
Argument 1 passed to Illuminate\Database\Eloquent\Builder::create() must be of the type array, object given, called in D:\xampp\htdocs\MySiteBackEnd\vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php on line 23
and my data is :
{
email : "Artin.zareie#yahoo.com"
family : "aa"
name : "aa"
password : "aaa"
password_confirmation : "aaa"
username : "a"
}
my backend signup function is :
public function signup(SignUpRequest $request)
{
User::create($request);
return $this->login($request);
}
my login code is :
public function login()
{
$credentials = request(['email', 'password']);
if (! $token = auth()->attempt($credentials)) {
return response()->json(['error' => 'ایمیل یا رمزعبور نامعتبر می باشد .'], 401);
}
return $this->respondWithToken($token);
}
and finaly , my SignUpRequest class is this :
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SignUpRequest 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',
'family' => 'required',
'email' => 'required|email|unique:users',
'username' => 'required|unique:users',
'password' => 'required|confirmed',
];
}
}
i'm using angular 6 and laravel 5.7
On your signup method just use
User::create($request->all());
instead of
User::create($request);
Related
I am trying to make a validation that will check whether at least one item is provided in an array following the steps in Custom Validation Rules
Routes.php
Route::middleware(['auth:api', 'bindings'])->group(function () {
Route::prefix('api')->group(function () {
Route::apiResources([
'exam-papers/{examPaper}/questions' => ExamPaperQuestionsController::class
]);
});
});
ValidateArrayElementRule.php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class ValidateArrayElementRule implements Rule
{
public function __construct()
{
//
}
public function passes($attribute, $value)
{
echo "there";
return count($value) > 0;
}
public function message()
{
return 'At least one element is required!';
}
}
ExamPaperQuestionsController.php
public function store(ExamPaperQuestionStoreRequest $request, ExamPaper $examPaper)
{
return response()->json([])->setStatusCode(201);
}
In my test file I have
public function error_422_if_no_questions_provided()
{
Permission::factory()->state(['name' => 'create exam paper question'])->create();
$this->user->givePermissionTo('create exam paper question');
$this->actingAs($this->user, 'api')
->postJson('/api/exam-papers/' . $this->examPaper->id . '/questions', [])
->assertStatus(422);
}
ExamPaperQuestionStoreRequest.php
class ExamPaperQuestionStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return auth()->user()->can('create exam paper question');
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
echo "HERE";
return [
'questions' => [new ValidateArrayElementRule],
'questions.*.description' => 'required'
];
}
}
The test is failing
Expected status code 422 but received 201.
I can see the text "HERE" is logged but "there" is not. Why is my validation passes() function not being called?
Suppose if your request contain empty then it wont call custom validation. So you must add required filed to ensure request has key questions
'questions' => ["required",new ValidateArrayElementRule]
Incase questions is optional and if entered then at least two or three item required then you can use required if validation.
By default laravel support min in array
'questions' => ["required","array","min:1"]
why not to use the simple method in validation? :
$request->validate([
'title' => 'required|min:5|max:20',
'detail' => 'required',
'cat_image' => 'required',
]);
I am new in laravel. I have created login and signup form using auth command.
I have activated the email verification for login. Also I have created the social login for Gmail,Fb etc. using the socialite based on below link.
https://www.tutsmake.com/laravel-6-google-login-tutorial-with-socialite-demo-example/
Now I don't require email verification for those user who login through social but mandatory for manual signup.
My Homecontroller
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(['auth', 'verified']);
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('frontend.index');
}
public function seedr()
{
$users=DB::table('users')->get();
return view('backend.seedr',['users'=>$users]);
}
}
My SocialController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Validator,Redirect,Response,File;
use Socialite;
use App\User;
class SocialController extends Controller
{
public function redirect($provider)
{
//echo $provider;die;
return Socialite::driver($provider)->redirect();
}
public function callback($provider)
{
$getInfo = Socialite::driver($provider)->user();
$user = $this->createUser($getInfo,$provider);
auth()->login($user);
return redirect()->to('/home');
}
function createUser($getInfo,$provider){
$user = User::where('provider_id', $getInfo->id)->first();
if (!$user) {
//$mytime = Carbon::now();
$currenttime=date("Y-m-d h:i:s a", time());
$user = User::create([
'name' => $getInfo->name,
'email' => $getInfo->email,
'provider' => $provider,
'provider_id' => $getInfo->id,
]);
//die;
}
return $user;
}
}
You probably have a column email_verified_at that stores the date when the email address was verified, by default it's null which means the user is not verified. In your SocialController#createUser set it to the current date:
$user = User::create([
'name' => $getInfo->name,
'email' => $getInfo->email,
'provider' => $provider,
'provider_id' => $getInfo->id,
'email_verified_at' => now()
]);
You can use markEmailAsVerified()
$user = User::create([
'name' => $getInfo->name,
'email' => $getInfo->email,
'provider' => $provider,
'provider_id' => $getInfo->id,
]);
$user->markEmailAsVerified();
Do NOT use it as the #Raftel mentioned! When you add email_verified_at to your $fillable variable, then hacker could break your whole Email Verification by sending a hidden input (e.g. <input type="hidden" name="email_verified_at" value="<?php echo now() ?>"/ >...
You can use undocumented method on eloquent models called forceFill() instead: https://www.mike-griffiths.co.uk/blog/laravels-forcefill-and-forcecreate/
hello i want to add user when admin log in. i use default Register form.
it success but remember_token is missing and parssword not decrypt.
this is my controller :
public function create()
{
return view('admin/dosen.create');
}
public function store(CreateDosenRequest $request)
{
User::create($request->all());
return redirect('admin/dosen')->with('message', 'Data berhasil ditambahkan!');
}
and my request :
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required|max:255',
'username'=>'required|unique:users',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
];
}
Route :
Route::resource('/admin/dosen', 'AdminController',
['except => show, index']);
});
<form method="post" action="#"><input type="hidden" name="_token" value="{{csrf_token()}}"></form>
Just add this in html form.Working :)
Is it possible for me to create a redirect from within the authorize() function on a request? I have tried the following code, but it doesn't fulfill the redirect request. Can anyone shed any light on this?
Thanks.
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use App\Reserve;
use Cookie;
use Config;
class ClassVoucherCheckoutRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize(Reserve $reserve, Cookie $cookie)
{
if((!$cookie->has(Config::get('app.cookie_name'))) || ($reserve->where('cookie_id', $cookie->get(Config::get('app.cookie_name')))->count() == 0))
{
return redirect()->to('butchery-voucher')->withErrors('Your reservation has expired. Places can only be held for up to 30 minutes.');
}
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
];
}
}
I also have the same issue, I did not find any solution yet but I have do this by an another way, I know this is not the right solution but may be help for now.
My problem is: I need to register an user if any other user with same fb_id did not exists in database. But I was unable to check this condition because the middelware execute before the controller and it returns me the fb_id already taken error.
This is my UserController:
public function createUser (UserRequest $request) {
/** here I need to redirect user if the given `fb_id` is already exists
before it was always returning the `fb_id` exists error before executing
the following code, because all input filtered by the `UserRequest` middleware
I have changed the `UserRequest.php` to execute the following code.
**/
$fb_id = Input::get('fb_id');
$user = $this->user->getUserWhereFbIdIn([$fb_id]);
if(sizeof($user) > 0){
return Response::json(['result' => true, 'error' => false, 'message' => 'User exists', 'data' => $user]);
}
// insert user code is here
}
UserRequest.php:
public function authorize()
{
return true;
}
public function rules()
{
$fb_id = Input::get('fb_id');
$user = User::where('fb_id', $fb_id)->get()->toArray();
if(sizeof($user) > 0){
return [];
}
return [
'fb_id' => 'required|unique:users',
'username' => 'required|unique:users',
'email' => 'required|unique:users',
'image' => 'required',
'device_id' => 'required',
'status' => 'required',
];
}
I think the most elegant solution is to make the authorize() return false when you want to redirect, and override the forbiddenResponse() method on the FormRequest class. The drawback is that you'll either have to perform the condition logic twice, or set a state variable.
class MyRequest extends FormRequest
{
public function authorize(): bool
{
return Auth::user()->hasNoEmail() ? false : true;
}
public function forbiddenResponse(): Response
{
if Auth::user()->hasNoEmail() return redirect(route('user.should_provide_email'));
return parent::forbiddenResponse();
}
public function rules(): array
{
return [];
}
}
Of course, the argument could be made that such redirects should always take place in a middleware applied to specific groups of routes, but having the option to do it in a Request class can be nice.
I use the included authentication of laravel 5.1.6 and want to know how I can extend it, to work like this:
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// The user is active, not suspended, and exists.
}
If the user is not "active", the login should not be possible. I have an 'active' column in the users table , with 0 or 1 as value. How can i do this while still using the built in authentication with login throtteling.
edit:
I don't have a postLogin function in the AuthController, only a use AuthenticatesAndRegistersUsers, ThrottlesLogins; , a __construct(), a validator() and a create() function. Do I have to change something in the trait in Illuminate\Foundation\Auth\.. or must I add the the postLogin() function in the AuthController ?
You can just override the getCredentials() method in your AuthController:
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers;
public function getCredentials($request)
{
$credentials = $request->only($this->loginUsername(), 'password');
return array_add($credentials, 'active', '1');
}
}
This will add the active = 1 constraint when trying to authenticate a user.
EDIT: If you want a separate error message like BrokenBinary says, then Laravel allows you to define a method called authenticated that is called after a user has been authenticated, but before the redirect, allowing you to do any post-login processing. So you could utilise this by checking if the authenticated user is active, and throw an exception or display an error message if not:
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers;
public function authenticated(Request $request, User $user)
{
if ($user->active) {
return redirect()->intended($this->redirectPath());
} else {
// Raise exception, or redirect with error saying account is not active
}
}
}
Don’t forget to import the Request class and User model class.
I have now changed the auth middleware /app/Http/Middleware/Authenticate.php (added the block below the comment):
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/login');
}
}
#logout if user not active
if($this->auth->check() && $this->auth->user()->active !== 1){
$this->auth->logout();
return redirect('auth/login')->withErrors('sorry, this user account is deactivated');
}
return $next($request);
}
It seems, it also logs out inactive users if they were already logged in.
I would add following first thing in postLogin() function.
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
if ($this->auth->validate(['email' => $request->email, 'password' => $request->password, 'active' => 0])) {
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors('Your account is Inactive or not verified');
}
active is a flag in user table. 0 = Inactive, 1 = active. so whole function would look like following..
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
if ($this->auth->validate(['email' => $request->email, 'password' => $request->password, 'active' => 0])) {
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors('Your account is Inactive or not verified');
}
$credentials = array('email' => $request->email, 'password' => $request->password);
if ($this->auth->attempt($credentials, $request->has('remember'))){
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => 'Incorrect email address or password',
]);
}
Solved: this link ( tutorial) will help you : https://medium.com/#mshanak/solved-tutorial-laravel-5-3-disable-enable-block-user-login-web-passport-oauth-4bfb74b0c810
step1:
add new field to the User table called ‘status’ (1:enabled, 0:disabed)
step2:
to block the web login , in app/Http/Controllers/Auth/LoginController.php add the follwoing function:
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(\Illuminate\Http\Request $request)
{
$credentials = $request->only($this->username(), ‘password’);
return array_add($credentials, ‘status’, ‘1’);
}
Step3:
to block the user when using passport authentication ( token ) , in the User.php model add the following function :
public function findForPassport($identifier) {
return User::orWhere(‘email’, $identifier)->where(‘status’, 1)->first();
}
Done :)
On Laravel 5.3.* update app/Http/Controllers/Auth/LoginController
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(\Illuminate\Http\Request $request)
{
$credentials = $request->only($this->username(), 'password');
return array_add($credentials, 'active', '1');
}
// your code here