I have problems getting Cookie, I define a cookie in one middleware "CheckReferral", but when I call the cookie in one Controller the cookie return null, I check the cookie in the browser, and the cookie is good in the browser, I don't know what is the problem with the cookie... I've googled too much and this is my last resource, Someone can help me?
Here is the code of the middleware:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckReferral
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($request->hasCookie('referral')) {
return $next($request);
} else {
if ($request->query('ref')) {
return redirect($request->fullUrl())->withCookie(cookie()->forever('referral', $request->query('ref')));
}
}
return $next($request);
}
This is how I call the cookie in the controller:
protected function create(array $data)
{
// $referred_by = User::where( 'affiliate_id', Cookie::get( 'referral' ) )->first();
// $referred_user = Cookie::get( 'referral' );
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'affiliate_id' => $this->uniqueRandomString(),
'referred_by' => Cookie::get('referral'),
]);
}
Here is the cookie stored in the browser:
Here is the database... the field referred_by, is stored as null, but should store the Value of the cookie:
Thank a lot, I hope resolve the problem, and know the cause...
Make sure you've defined that middleware in app\Http\Kernel.php. Specifically in the 'web' array there.
Imported the middleware in your web.php ( routes ) file.
..and finally added that middleware for your route like so:
Route::web('/', ['middleware' => CheckReferral']
If you've already done so then make sure you've added referred_by column to the $fillable[] array of your User model.
Edit.
This will do:
\Request::cookie('referral');
I've solved it using vanilla PHP, the global variable $_COOKIE
protected function create(array $data)
{
// $referred_by = User::where( 'affiliate_id', Cookie::get( 'referral' ) )->first();
// $referred_user = Cookie::get( 'referral' );
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'affiliate_id' => $this->uniqueRandomString(),
'referred_by' => $_COOKIE['referral'],
]);
}
Where Cookie::get('referral') is $_COOKIE['referral'] is not a Elegant solution, but work...
Related
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);
}
}
I use Laravel to submit a form. Here is my web.php routes :
Route::middleware(['auth'])->prefix('account')->namespace('Account')->group(function () {
Route::get('informations', 'AccountController#index')->name('account.informations');
Route::post('informations', 'AccountController#update')->name('account.informations.post');
});
My Controller AccountController.php :
/**
* #param UpdateMember $request
* #return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateUser $request)
{
dd($request->all());
$user = User::where('id', Auth::user()->id)
->update($request->all());
return redirect()->route('account.informations');
}
And my UpdateUser.php :
/**
* 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 [
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users|confirmed',
'password' => 'required|string|min:6|confirmed',
];
}
My problem : when I use UserUpdate $request in my controller, I don't reach the function, the dd($request->all()) is not shown.
But if I replace :
public function update(UpdateUser $request)
By
public function update(Request $request)
My controller is reached. What do I do wrong ?
what about the unique field validation like email because your validation rules returns a error email already exists while updating a existing record. This can be solved as example below
public function rules()
{
$client = Client::find($this->client);
return [
'name' => 'required|string',
'address' => 'required|string',
'gender' => 'required|string',
'dob' => 'required|string',
'phone' => 'required|string',
'email' => 'required|unique:clients,email,' . $client->id,
'password' => 'regex:/^[0-9a-zA-Z]*$/',
'profile-photo' => 'image|mimes:jpg,png,jpeg',
'c_name' => 'nullable|regex:/^[a-zA-Z ]*$/',
'c_address' => 'nullable|regex:/^[a-zA-Z ]*$/',
'c_email' => 'nullable|email|unique:clients,company_email,'. $client->id,
'c_contact' => 'nullable|regex:/^[0-9]*$/',
];
}
In my case, the reason was that I forgt to add "Accept: application/json" in the request header. After adding that header everything worked fine
I'm using the Laravel Auth to make users able to register. What I'm now trying is: After users register (if they have a special role selected), there is another row inserted into another table (then users) which holds the relating user id. This is the code for it:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use App\Complaint;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* 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|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
'username' => 'required|unique:users',
'role' => 'required'
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
$user = new User;
$user->name = $data['name'];
$user->email = $data['email'];
$user->username = $data['username'];
$user->password = bcrypt($data['password']);
$user->role = $data['role'];
$user->templateURL = "";
/*$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);*/
$user->save();
if($data['role'] == 'Verkäufer'){
$complaintRow = Complaint::create([
'user_id' => $user->id,
'complaintCount' => 0
]);
}
switch($data['role']){
case 'Käufer':
$user->attachRole(2);
break;
case 'Verkäufer':
$user->attachRole(3);
break;
default:
$user->attachRole(2);
break;
}
return $user;
}
}
But it's not working correctly, the user is inserted as well as a row for the complaints, but somehow $user->id seems to be null, the column always has user_id set to 0. Any ideas why this could be like this?
EDIT: I got it working now... It was actually not the code I posted, I just didn't make the user_id field fillable in the complaint table, that's why there was 0 in always, because 0 was the default value, so it just didn't set it.
Thanks all for the answers anyway.
As per Laravel Eloquent ORM, $user->id will return the Id of user.
If you are getting null, then there might be error in saving. (https://stackoverflow.com/a/21084888/6628079)
Try printing $user after saving it.
UPDATE:
It would be better if you add data in complaint table if user is saved successfully.
protected function create(array $data)
{
$user = new User;
$user->name = $data['name'];
$user->email = $data['email'];
$user->username = $data['username'];
$user->password = bcrypt($data['password']);
$user->role = $data['role'];
$user->templateURL = "";
/*$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);*/
if ($user->save()) {
if ($data['role'] == 'Verkäufer') {
$complaintRow = Complaint::create([
'user_id' => $user->id,
'complaintCount' => 0
]);
}
switch ($data['role']) {
case 'Käufer':
$user->attachRole(2);
break;
case 'Verkäufer':
$user->attachRole(3);
break;
default:
$user->attachRole(2);
break;
}
return $user;
} else {
// Your code if user doesn't save successfully.
}
}
This is because, Eloquent save method bool but not the instance of newly created Entity. For confirmation checkout this link: https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html
So, if you want to get the newly created instance you can either user create method or make another query to get newly inserted instance. First one is better ans easy. Here is how you can do it:
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);
Now, you have $user variable containing User instance. But to do this you need to consider fillable/guared issue in your model. I mean, in your model you have to add the following line:
protected $fillabe = ['name', 'email', 'username', 'password', 'role', 'templateURL']
Is column id exists?
Try to set $primaryKey = 'id' on model (user).
After $user->save you can access to id like $user->id
Or after $user->save try to get max id from your table.
$user = User::select('id')->max('id')->first();
Try this:
$lastId = User::create($userData)->id;
$user->id will tell you created user's ID right after using save() method.
You did all most correct you just need to change,
when you are saving user object it will return saved user object so just grab that object and use in furcher conditions.
$saved_user = $user->save();
if(!empty($saved_user)){
if($data['role'] == 'Verkäufer')
{
$complaintRow = Complaint::create([
'user_id' => $saved_user->id,
'complaintCount' => 0
]);
}
} else {
throw new error(500);
}
Hope this will help thanks :)
I'm using the default Laravel 5.1 user registration. I have two tables: users and shops. When user registers, the app should insert a user in the table users, get the id and use it to register a shop. I've been reading the default AuthController.php but i didn't find anything. Here is the AuthController if it helps.
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
/**
* 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|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
//'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
/**
* Get the path to the login route.
*
* #return string
*/
public function loginPath()
{
return route('login');
}
/**
* Get the post register / login redirect path.
*
* #return string
*/
public function redirectPath()
{
return route('home');
}
}
Solved, but now I have a Integrity constraint violation. Is this code correct?
protected function create(array $data)
{
$user = new User([
'email' => $data['email'],
'password' => bcrypt($data['password'])
]);
$user->role = 'shop_owner';
$user->remember_token = str_random(10);
$user->save();
$userId = $user->id;
Shop::create([
'name' => $data['s_name'],
'address' => $data['s_address'],
'CP' => $data['s_pcode'],
'Telephone' => $data['s_tlf'],
'contact_name' => $data['cp_name'],
'contact_num' => $data['cp_tlf'],
'id_user' => $userId
]);
return $user;
}
There you go:
protected function create(array $data)
{
$user = User::create([
//'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
$userId = $user->id;
Shop::create([... use $userId here ...]);
return $user;
}
This goes to your controller:
public function store(Request $request) {
$user = User::create(Input::all());
$user->save();
$shop = Shop::create([..enter shop attributes or leave blank..]);
$user->shop()->save($shop);
}
You need to place the following code at the top of the Auth Controller
use App\Shop;
I have a users table which holds every detail of the user including a field called 'isActive' which is a Boolean.
I want to log in the user if the 'isActive = 1' and also i want to redirect the user back to the login page if the 'isActive = 0'.
My code is below:
public function postSignIn(Request $request)
{
$this->validate($request, [
'username' => 'required',
'password' => 'required'
]);
if(Auth::attempt(['username' => $request['username'], 'password' => $request['password']])) {
return redirect()->route('home');
}
}
The code above allows me to sign normally. With or without the isActive field being called.
As per Documentation,
If you wish, you also may add extra conditions to the authentication
query in addition to the user's e-mail OR username and password. For
example, we may verify that user is marked as "active":
In your case, you just need to add 'isActive' => 1 in array.
Your code should be:-
if (Auth::attempt(['username' => $request['username'], 'password' => $request['password'],'isActive' => 1])) {
// The user is active, not suspended, and exists.
}
else{
// The user is Inactive, suspended, or not exists.
return redirect()->route('home');
}
Simply add the extra field into the attempt method
if(Auth::attempt([
'username' => $request['username'],
'password' => $request['password'],
'isActive' => 1,
])
)
{
return redirect()->route('home');
}
This is all covered in the documentation.
I don't know where you guys are getting your code from as mine is massively different. Are you guys upgrading to 5.2 or installing it through a fresh install of 5.2? Here's what I have in my login method:
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
I didn't want to override the remember functionality, so I use this way:
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function getCredentials(Request $request)
{
$request = $request->only($this->loginUsername(), 'password');
$request['active'] = true;
return $request;
}
Basically add $request['active'] = true; to the getCredential method in your App/Http/Controllers/Auth/AuthController and Bob's your uncle.