I am doing a password reset and sending email with Notification.
I created ResetPasswordNotification. I added the sendPasswordResetNotification method inside the User.php model.It works successfully. But since my User model is working in another common project, where can I write the sendPasswordResetNotification method outside of the User.php model.
my User.php model
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
In short, how can I use a method other than the user.php model to exclude the sendPasswordResetNotification method in the canResetPassword trait?
In the project where I use Notification, I opened the user model and extended the common user model and added the sendPasswordResetNotification method there. I produced a solution in this way.
Related
I have a boilerplate Laravel app, with a model generated with the cli command php artisan make:model Post -a --api to make an API controller, with form request and policies.
The Laravel Policy Authorisation docs doesn't seem to make it clear what to do with both a Policy and FormRequest. Do I call the policy class inside the FormRequest? Or ignore the policies for store/update?
How do I use auth policies with FormRequests for my API controller?
Version
Laravel 9
Although its not told directly in the docs. You can use the policy inside the authorize() method in a Form Request :
Authorization Using Model
class UpdatePostRequest extends FormRequest
{
public function authorize() : bool
{
return $this->user()->can(
'update', $this->post
);
}
}
Controller
class PostController
{
public function update(UpdatePostRequest $request, Post $post)
{
// your code here
}
}
So Instead of using $this->authorize('update', $post) inside the controller you can directly put it inside the FormRequest.
Hope it helps : )
Docs didn't make it clear, posting incase anyone else is struggling. Example for User model, UserPolicy and UserController.
First, add the Policy class in AuthServiceProvider.
App\Providers\AuthServiceProvider
/**
* The policy mappings for the application.
*
* #var array<class-string, class-string>
*/
protected $policies = [
User::class => UserPolicy::class,
];
Second, use authorizeResources in the controller to auto map policies to the api controller. See here for what the policy -> controller maps to
// App\Http\Controllers\UserController
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Requests\StoreUserRequest;
use App\Http\Requests\UpdateUserRequest;
class UserController extends Controller
{
/**
* Create the controller instance.
*
* #return void
*/
public function __construct()
{
// Sets up user policy for this controller
$this->authorizeResource(User::class, 'user');
}
...
}
Last, DELETE the authorize section from the FormRequests
// App\Http\Requests\UpdateUserRequest
class UpdateUserRequest extends FormRequest
{
// DELETE the auth part below, otherwise it'd mess up using policies.
// I'm pretty sure this takes precedence over policies
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
//public function authorize()
//{
//return true;
//}
}
Now the policies set in UserPolicy will be used as auth guards for the User Controller.
I wanted to make a program that able to store a data and every the data that i send to the Database must contain the Email from user used to login to my Web. In here i'm using Myth Auth library as authenticator and login security. But i can't find the method to call the current Email so i can fetch it and push to my Database. i'm using MySql as my DB.
You have to create an Entity extending Mith's one.
So create app/Entities/User.php
Then... to use:
echo user()->getEmail();
See Documentation:
https://github.com/lonnieezell/myth-auth/blob/develop/docs/extending.md
<?php namespace App\Entities;
use Myth\Auth\Entities\User as MythUser;
class User extends MythUser
{
/**
* Returns Email
*
* #return string
*/
public function getEmail()
{
return trim(trim($this->attributes['email']));
}
}
add the following method to myth-auth\src\Entities\User.php
public function getEmail()
{
return trim(trim($this->attributes['email']));
}
then, anywhere in your app, you can call it with user()->getUsername()
You can do the same for username or any of the other user attributes.
A!
Now that we have our new entity, we need to update our UserModel to return it instead of the default Myth:Auth version:
class UserModel extends MythModel
{
protected $returnType = 'App\Entities\User';
...
In Laravel Framework 5.4.18 I just ran php artisan make:auth
When I request to reset my password, I get an email that says
(...)
You are receiving this email because we received a password reset
request for your account
(...)
Where is the file where it is specified to say that? I want to change it completely.
Notice that here is how to change (only) the general appearance of any notification, and that here is how to change (in addition) the body of the notification.
Thank you very much.
Your User model uses the Illuminate\Auth\Passwords\CanResetPassword trait. This trait has the following function:
public function sendPasswordResetNotification($token)
{
// use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification
$this->notify(new ResetPasswordNotification($token));
}
When a password reset is requested, this method is called and uses the ResetPassword notification to send out the email.
If you would like to modify your reset password email, you can create a new custom Notification and define the sendPasswordResetNotification method on your User model to send your custom Notification. Defining the method directly on the User will take precedence over the method included by the trait.
Create a notification that extends the built in one:
use Illuminate\Auth\Notifications\ResetPassword;
class YourCustomResetPasswordNotification extends ResetPassword
{
/**
* Build the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('This is your custom text above the action button.')
->action('Reset Password', route('password.reset', $this->token))
->line('This is your custom text below the action button.');
}
}
Define the method on your User to use your custom notification:
class User extends Authenticatable
{
public function sendPasswordResetNotification($token)
{
$this->notify(new YourCustomResetPasswordNotification($token));
}
}
First open a terminal and go to the root of the application and run the following command:
php artisan vendor:publish
You will see some files copied, you can find the email template files in
Root_Of_App/resources/views/vendor
You can edit the Email templates for notifications there.
I'm creating a system in which there are users, and user have many user roles. The user roles also contain permissions. Some fields are protected, so that they cannot be overwritten without the user possessing a specific permission.
For example, a user may have the attribute "email" which cannot be changed by the user, unless the user has the permission "update-email-address".
I originally intended to implement this concept as a trait or an abstract class, but I can't figure a way of doing this which doesn't involve either overloading the Eloquent Model constructor method, or else completely overloading another method.
What I'm hoping to do, is to be able to specify an array in a model like below, and by using a tract or extention, somehow prevent updating a model attribute:
/**
* The attributes that should only be updatable by given user with the
* specified permission
*
*/
public $update_only_by_permission = [
'email' => ['update-email-address'],
];
Is there a way to achieve this?
I stumbled across a way to provide a boot method for a trait extending a model, and was able to achieve this through the following:
Trait used on many Eloquent Models:
use Auth;
trait AttributeVisibleByPermissionTrait {
/**
* Stops updating of the object attributes if the authenticated
* user does not have the given permission provided in the
* $object->update_only_by_permission array.
*/
public static function bootAttributeVisibleByPermissionTrait(){
static::updating(function($object){
foreach ($object->update_only_by_permission as $attribute => $permissions) {
foreach ($permissions as $permission) {
if(!Auth::User()->can($permission)) {
unset($object->$attribute);
}
}
}
});
}
}
User Model:
class User extends Authenticatable
{
use AttributeVisibleByPermissionTrait;
/**
* The attributes that should only be updated by given user auth permissions
*
* #var array
*/
public $update_only_by_permission = [
'email' => ['update-email-address'],
];
}
When login correct username & password then show error
ErrorException
Argument 1 passed to
Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an
instance of Illuminate\Auth\UserInterface, instance of User given,
called in
E:\xampp\htdocs\laravel\vendor\laravel\framework\src\Illuminate\Auth\Guard.php
on line 316 and defined
Anybody know where problem?
Your User model MUST implement UserInterface and its methods:
<?php namespace Illuminate\Auth;
interface UserInterface {
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier();
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword();
}
So it must declared as something like
use Illuminate\Auth\UserInterface;
class User extends Eloquent implements UserInterface {
}
This error might also appear when you use a different model for users (example :member)
if it's the case you need to update Authentication Model and Authentication Table in app/config/auth.php with the appropriate model / database table.