I am working on a Web Application using Laravel-5.8 as the backend. I am combining two classes: User and Role
ApiController.php
public function store(Request $request)
{
if(!Auth::user()->hasPermissionTo('Add Users'))
return response()->json([ "message" => 'User do not have permission'], 401);
$request->validate([
'name' => 'required|string|min:2',
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed|min:6'
]);
$user = new User([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'activation_token' => str_random(60),
'address' => $request->email,
'about' => $request->email,
]);
if($request->role)
foreach($request->role as $role)
$user->assignRole($role);
else {
return response()->json([
'error' => 'Role Not Found!'
], 401);
}
$user->school_id = Auth::user()->school_id;
if($request->address)
$user->address = $request->address;
if($request->about)
$user->about = $request->about;
$user->save();
$avatar = Avatar::create(strtoupper($user->name))->getImageObject()->encode('png');
Storage::put('avatars/'.$user->id.'/avatar.png', (string) $avatar);
$user->notify(new SignupActivate($user));
return response()->json([
'message' => 'Successfully Added New User!'
], 201);
}
From the code above, I don't want to display all the Roles. I want to use the foreach statement to only select and display these two Roles: Admin, Staff.
That is, where role_name = Admin, Staff.
foreach($request->role as $role)
$user->assignRole($role);
How do I achieve this?
I think you can go about that in this way.
You can use the Laravel filter method which is in the documentation here Laravel Collection filter Method
This method returns an array of items that have passed a given condition
You convert your roles request into a collection first
Then use a condition like
return if($role == 'Admin' || $role == 'Staff')
Where you see return $value > 2;
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->filter(function ($value, $key) {
return $value > 2;
});
$filtered->all();
// [3, 4]
Related
I am trying to store logged user's id but I am getting this error
ErrorException
array_map(): Argument #2 should be an array
This is the code in the controller
public function store(Request $request)
{
if (!auth()->check()) {
abort(403, 'Only authenticated users can create new posts.');
}
$data = request()->validate([
'id' => $id = Auth::id(),
'content' => 'required',
'topic' => 'required',
'hashtag' => 'required'
]);
$check = Tweets::create($data);
return Redirect::to("form")->withSuccess('Great! Form successfully submit with validation.');
}
The error is in this line of code.
'id' => $id = Auth::id(),
I know that should be a string but to explain to you what I am trying to do, and I still have not found any solution.
Do it Like this.
public function store(Request $request)
{
if (!auth()->check()) {
abort(403, 'Only authenticated users can create new posts.');
}
$request->validate([
'content' => 'required',
'topic' => 'required',
'hashtag' => 'required'
]);
$data = $request->all();
$data['id'] = Auth::id();
$check = Tweets::create($data);
return Redirect::to("form")->withSuccess('Great! Form successfully submit with validation.');
}
Delete this
'id' => $id = Auth::id(),
and add
$data['id'] = Auth::id();
before
$check = Tweets::create($data);
That should work
I am using backpack laravel. Though I am also using Backpack's own authentication, yet I need to maintain a different customer table for App usage. For the customer table, I am using JWTAuth for token generation, but token generation gets failed each time.
public function register(Request $request)
{
$checkEmail = Customer::where('email', $request->email)->first();
if ($checkEmail) {
$response = [
'email_already_used' => true,
];
return response()->json($response);
}
$payload = [
'password' => \Hash::make($request->password),
'email' => $request->email,
'first_name' => $request->first_name,
'last_name' => $request->last_name,
'auth_token' => '',
];
try {
$user = new \App\Models\Customer($payload);
if ($user->save()) {
$token = self::getToken($request->email, $request->password); // generate user token
if (!is_string($token)) {
return response()->json(['success' => false, 'data' => 'Token generation failed'], 201);
}
$user = \App\Models\Customer::where('email', $request->email)->get()->first();
$user->auth_token = $token; // update user token
$user->save();
$response = [
'success' => true,
'data' => [
'id' => $user->id,
'auth_token' => $token,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => $user->email,
],
];
} else {
$response = ['success' => false, 'data' => 'Couldnt register user'];
}
} catch (\Throwable $e) {
echo ($e);
$response = ['success' => false, 'data' => 'Couldnt register user.'];
return response()->json($response, 201);
}
return response()->json($response, 201);
}
I believe there might be some issue with guards.
Do I need to specify something in app/config.php for this?
so I have this store function at my Controller
public function store(Request $request)
{
Penghuni::create([
'nama_penghuni' => $request->nama_penghuni,
'email' => $request->email,
'phone' => $request->phone,
'tower' => $request->tower,
'no_unit' => $request->no_unit
]);
User::create([
'name' => $request->nama_penghuni,
'email' => $request->email,
'password' => Hash::make($request['password']),
'role' => 'penghuni',
]);
return redirect(route('penghuni.index'));
}
what I want is make sure both insert is success, because the current result I got is when Penghuni create is done but the user is fails it keeps getting redirected
hope someone can help, I use laravel 5.8
thank you
This Code is Perfect check other things.
public function store(Request $request)
{
Penghuni::create([
'nama_penghuni' => $request->nama_penghuni,
'email' => $request->email,
'phone' => $request->phone,
'tower' => $request->tower,
'no_unit' => $request->no_unit
]);
User::create([
'name' => $request->nama_penghuni,
'email' => $request->email,
'password' => Hash::make($request['password']),
'role' => 'penghuni',
]);
return redirect(route('penghuni.index'));
}
1. Model
Penghuni and user Model must added this Line
protected $guarded = [];
Other Solution
public function store(Request $request)
{
$penghuni = new Penghuni;
$penghuni->nama_penghuni = $request->nama_penghuni;
$penghuni->email = $request->email;
$penghuni->phone = $request->phone;
$penghuni->tower = $request->tower;
$penghuni->no_unit = $request->no_unit;
$penghuni->save();
$user = new User;
$user->name = $request->nama_penghuni;
$user->email = $request->email;
$user->password = Hash::make($request->password);
$user->role = 'role';
$penghuni->users()->save($user);
return redirect(route('penghuni.index'));
}
You can wrap your queries in a database transaction like so:
DB::transaction(function () use ($request) {
// queries here
});
return redirect(route('penghuni.index'));
Or something like this, depending on your use-case.
DB::beginTransaction();
try {
// queries here
// all good
DB::commit();
return redirect(route('penghuni.index'));
} catch (\Exception $e) {
// something went wrong
DB::rollback();
}
You can read more about database transaction here: https://laravel.com/docs/8.x/database#database-transactions
I have some problem when I want to make login, I got an issue for my Auth::attempt always false value, Is am I got something wrong in my code?
Controller :
public function register(Request $register)
{
$validator = Validator::make($register->all(), [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors()], 401);
} else {
$name = $register->input('name');
$email = $register->input('email');
$pwd = $register->input('password');
$c_pwd = $register->input('c_password');
// Crypting password & c_password to md5
$md5_pwd = md5($pwd);
$md5_c_pwd = md5($c_pwd);
// Salt password & c_password
$password = crypt($md5_pwd, "asd");
$c_password = crypt($md5_c_pwd, "asd");
$data = new User();
if ($password == $c_password) {
$user = User::create([
'name' => $name,
'email' => $email,
'password' => $password,
]);
$success['token'] = $user->createToken('SSOApp')->accessToken;
return response()->json([
'success' => true,
'token' => $success,
'user' => $user
]);
} else {
return response()->json(['error' => "Password doesn't match"], 401);
}
}
}
public function login()
{
$email = request('email');
$pwd = request('password');
$md5 = md5($pwd);
$password = crypt($md5, "asd");
if (Auth::attempt(['email' => $email, 'password' => $password])) {
$user = Auth::user();
$success['token'] = $user->createToken('SSOApp')->accessToken;
return response()->json([
'success' => true,
'token' => $success,
'user' => $user
]);
} else {
return response()->json([
'success' => false,
'message' => 'Invalid Email or Password',
], 401);
}
}
I assume you messed up with Laravel Default Password Hashing System
public function register(Request $register)
{
$validator = Validator::make($register->all(), [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
'c_password' => 'required|same:password',
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors()], 401);
} else {
$name = $register->input('name');
$email = $register->input('email');
$pwd = $register->input('password');
$c_pwd = $register->input('c_password');
// $data = new User();
$user = User::create([
'name' => $name,
'email' => $email,
'password' => bcrypt($password . 'salt'),
]);
$success['token'] = $user->createToken('SSOApp')->accessToken;
return response()->json([
'success' => true,
'token' => $success,
'user' => $user
]);
}
}
public function login()
{
$email = request('email');
$pwd = request('password');
if (Auth::attempt(['email' => $email, 'password' => $password . 'salt'])) {
$user = Auth::user();
$success['token'] = $user->createToken('SSOApp')->accessToken;
return response()->json([
'success' => true,
'token' => $success,
'user' => $user
]);
} else {
return response()->json([
'success' => false,
'message' => 'Invalid Email or Password',
], 401);
}
}
Try this code. I don't know what happened to your code about the password you tried to encrypt it in attempt.
public function login(LoginRequest $request) {
if(!Auth::attempt([
'email' => $request->email,
'password' => $request->password,
'active' => true
])) {
return response()->json('Email or Password is incorrect', 500);
}
$this->user = Auth::user()->load('roles');
return $this->createUserAccessTokenResponse();
}
protected function createUserAccessTokenResponse() {
return response()->json([
'status' => 'success',
'data' => [
'token' => $this->user->createToken($this->user->name)->accessToken,
'user' => $this->user
],
], 200);
}
your problem is that laravel by default hashes the password. so when you do Auth::attempt it's going to hash the password you provided. And the result is what you get, it will always false.
Instead, you need to Other Authentication Methods.
Auth::login($user);
// Login and "remember" the given user...
Auth::login($user, true);
Above is the easiest way to fix your code.
It's recommended to hash your password rather than encrypting the password.
Hashing password in laravel is also
Hash::make($password);
And then you can use Auth::attempt to log in your user.
Laravel Auth uses the bcrypt hashing when saving password via model you may use either of the 2 method
$account->password = bcrypt("YOUR_PASSWORD"); or $account->password = Hash::make("YOUR_PASSWORD");
Then if you're dealing with the auth attempt function, just simply call the method like this
if($account = Auth::attemp(['email' => "YOUR_EMAIL#DOMAIN.COM", 'password' => "YOUR_PASSWORD"])){
//success login, do your extra job here
}else{
//invalid credentials here
}
Instead of using md5 or crypt use \Hash::make() it is much secure
I refactored your code and it does the same thing
You only need to rename your c_password to password_confirmation
Source
Below code does the same thing that your code do
public function register(Request $register)
{
$this->validate($register, [
'name' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed',
]);
$user = User::create([
'name' => $register->input('name'),
'email' => $register->input('email'),
'password' => $register->input('password'),
]);
$success['token'] = $user->createToken('SSOApp')->accessToken;
return response()->json([
'success' => true,
'token' => $success,
'user' => $user,
]);
}
public function login(Request $request)
{
$request->merge(['password' => \Hash::make($request->input('password'))]);
if (Auth::attempt($request->only(['email', 'password']))) {
$user = Auth::user();
$success['token'] = $user->createToken('SSOApp')->accessToken;
return response()->json([
'success' => true,
'token' => $success,
'user' => $user,
]);
}
return response()->json([
'success' => false,
'message' => 'Invalid Email or Password',
], 401);
}
when you hashing password using crypt it has a key to unlock it that's why there is a decrypt but when you use Hash::make() it doesn't have a key to break or unlock it, it will check it's algorithm to see if given password is matching the algorithm that already exists in the database that's why crypt is not safe and Hash::make is much much more safe
I want to add record using many to many relationship with Laravel 6.
I have a User which may have many roles like admin, blogger etc
Here is my function in User Model
public function roles()
{
return $this->belongsToMany(
'App\Role', 'user_roles', 'user_id', 'role_id', 'id'
);
}
Here is the Request data after form submission
array:5 [▼
"_token" => "asdnkasdjisajdmasnduajid"
"email" => "admin#admin.com"
"roles" => array:2 [▼
0 => "2"
1 => "3"
]
]
I have Tried this method to save my records
$users = [
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'status' => 'active',
];
$user = User::create($users);
if ($user) {
$role = $user->roles()->attach($request->roles);
if (!$role) {
Session::flash('error', "Unable to create Role at this moment");
return redirect()->back();
}
Session::flash('status', 'User Created Successfully');
return redirect()->back();
}
I am getting
Unable to create Role at this moment
The attach() method of a many to many relationship doesn't return anything.
Your role variable will therefore always be empty, even when a role is successfully attached to a user.
Try this instead:
$users = [
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'status' => 'active',
];
$user = User::create($users);
if (!$user instanceof User) {
Session::flash('error', "Unable to create User at this moment");
return redirect()->back();
}
$user->roles()->attach($request->roles);
if (!$user->roles) {
Session::flash('error', "Unable to create Role at this moment");
return redirect()->back();
}
Session::flash('status', 'User Created Successfully');
return redirect()->back();