Laravel 5.2注册后发送密码重置

Pac*_*cky 1 php laravel

我已经修改了我的authController.php文件来完成项目所需的一些操作.它工作得很好,只需要再做一次改动.现在控制器看起来像这样:

    <?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Role;
use Mail;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\Request;

use Illuminate\Foundation\Auth\ResetsPasswords;

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, ResetsPasswords;

    /**
     * Where to redirect users after login / registration.
     *
     * @var string
     */
    protected $redirectTo = '/add';

    /**
     * Create a new authentication controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware($this->guestMiddleware(), ['except' => 'logout']);


    }


     /**
     * Overwrite the Laravel 5.2 standard registration 
     * so user will not be logged in automatically.
     *
     * @param  array  $request
     * @return Register
     */
    public function register(Request $request)
    {
        $validator = $this->validator($request->all());

        if ($validator->fails()) {
            $this->throwValidationException(
                $request, $validator
            );
        }

        $this->create($request->all());

        return redirect($this->redirectPath());
    }

    /**
     * Extend password reset email to user for when registering
     */

    public function sendResetLinkEmail(Request $request)
    {
        $this->validateSendResetLinkEmail($request);

        $broker = $this->getBroker();

        $this->subject = "First Time User Setup";
        $broker->emailView = "auth.emails.password";

        $response = Password::broker($broker)->sendFirstTimeSetup(
            $this->getSendResetLinkEmailCredentials($request),
            $this->resetEmailBuilder()
        );

        switch ($response) {
            case Password::RESET_LINK_SENT:
                return $this->getSendResetLinkEmailSuccessResponse($response);
            case Password::FIRST_TIME_SETUP:
                return $this->getSendFirstTimeSetupEmailSuccessResponse($response);
            case Password::INVALID_USER:
            default:
                return $this->getSendResetLinkEmailFailureResponse($response);
        }
    }

    public function getSendFirstTimeSetupEmailSuccessResponse($response) 
    {
        return redirect()->back()->with('status', trans($response));
    }


    /**
     * 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, [
            'first-name' => 'required|max:255',
            'last-name' => 'required|max:255',
            'phone' => 'required|max:255',
            'form' => 'max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|min:6|confirmed',
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return User
     */
    protected function create(Request $request,  array $data ) 
    {
        //Create the user
        $user = User::create([
            'first_name' => $data['first-name'],
            'last_name' => $data['last-name'],
            'phone' => $data['phone'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);

        return $this->postEmail($request);

        /*
        Mail::send('auth.emails.registered', ['user' => $user], function ($m) use ($user) 
        {
            $m->to($user->email, $user->first_name)->subject('You Have Been Added');
        });*/

        //Is it a User? Then give them that role
        if ($data['user-role'] == 'user')
        {
            $role = Role::where('name', '=', 'user')->firstOrFail();
            $user = User::find($user->id);
            $user->roles()->attach($role->id);
        }

        //Is it an Admin? Then give them that role
        if ($data['user-role'] == 'admin')
        {
            $role = Role::where('name', '=', 'owner')->firstOrFail();
            $user = User::find($user->id);
            $user->roles()->attach($role->id);
        }

        return $user;
    }





}
Run Code Online (Sandbox Code Playgroud)

它会在用户创建时停止自动登录,根据表单为用户分配角色并发送密码重置电子邮件.麻烦不是我得到错误Trait method guestMiddleware has not been applied, because there are collisions with other trait methods on App\Http\Controllers\Auth\AuthController

Ohg*_*why 5

其中一个技巧就是了解工厂traits内部的Auth工作原理.

首先,我们需要使用use Illuminate\Foundation\Auth\ResetsPasswords;Trait以及特征AuthenticatesAndRegistersUsersThrottlesLogins特征.

use AuthenticatesAndRegistersUsers, ThrottlesLogins, ResetsPassword;
Run Code Online (Sandbox Code Playgroud)

接下来,我们需要确保将一个$request实例传递给我们的create方法:

protected function create(Illuminate\Http\Request $request, array $data)
Run Code Online (Sandbox Code Playgroud)

旁注 - 我建议远离传递一个$data对象作为参数,而不是使用$request.你可以得到这样的数据:$request->get('first-name')等.

最后,我们将我们传递$requestpostEmail()函数:

return $this->postEmail($request);
Run Code Online (Sandbox Code Playgroud)

这会将$请求传递给ResetsPasswords\postEmail函数:

public function postEmail(Request $request)
{
    return $this->sendResetLinkEmail($request);
}
Run Code Online (Sandbox Code Playgroud)

这将把它管道到ResetsPasswords\sendResetLinkEmail函数:

public function sendResetLinkEmail(Request $request)
{
    $this->validateSendResetLinkEmail($request);

    $broker = $this->getBroker();

    $response = Password::broker($broker)->sendResetLink(
        $this->getSendResetLinkEmailCredentials($request),
        $this->resetEmailBuilder()
    );

    switch ($response) {
        case Password::RESET_LINK_SENT:
            return $this->getSendResetLinkEmailSuccessResponse($response);
        case Password::INVALID_USER:
        default:
            return $this->getSendResetLinkEmailFailureResponse($response);
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个最终会发送一封电子邮件.

使整个过程工作的关键是Illuminate\Http\Request始终包含一个email字段的实例.

注意

response将从返回sendResetLinkEmail功能可能不是你发出同样的反应.也许用户在Password Reset创建帐户时会被请求弄糊涂.相反,也许你想发送一个First Time Setup.为此,您需要创建自己的Password BrokerPassword Facade.

接下来,让我们创建2个新目录:

App\Brokers
App\Facades 
Run Code Online (Sandbox Code Playgroud)

接下来,在其中创建一个新文件App\Facades并调用它Password.php.命名空间相应的文件并扩展现有的密码门面.此外,我们将添加另一个const作为我们的可观察响应类型FIRST_TIME_SETUP.

<?php

namespace App\Facades;

class Password extends \Illuminate\Support\Facades\Password {
    /**
     * Constant representing a successfully sent reminder.
     *
     * @var string
     */
    const FIRST_TIME_SETUP = 'passwords.first_time_setup';
}
Run Code Online (Sandbox Code Playgroud)

现在我们添加了另一种响应类型,我们可以switch在其中指示我们如何发送电子邮件.

接下来,我们需要制作Password Broker并建立我们的sendFirstTimeSetup功能.

namespace App\Brokers;

class PasswordBroker extends Illuminate\Auth\Passwords\PasswordBroker {
    public function sendFirstTimeSetup(array $credentials, Closure $callback = null) 
    {
        // First we will check to see if we found a user at the given credentials and
        // if we did not we will redirect back to this current URI with a piece of
        // "flash" data in the session to indicate to the developers the errors.
        $user = $this->getUser($credentials);

        if (is_null($user)) {
            return static::INVALID_USER;
        }

        // Once we have the reset token, we are ready to send the message out to this
        // user with a link to reset their password. We will then redirect back to
        // the current URI having nothing set in the session to indicate errors.
        $token = $this->tokens->create($user);

        $this->emailResetLink($user, $token, $callback);

        return static::FIRST_TIME_SETUP;
    }        
}
Run Code Online (Sandbox Code Playgroud)

现在我们需要复制sendResetLinkEmail我们之前看到的函数,并将其移动到我们的函数中AuthController.这将允许我们修改Password我们使用的Facade,并修改我们的switch声明以支持我们的First Time Setup

public function sendResetLinkEmail(Request $request)
{
    $this->validateSendResetLinkEmail($request);

    $broker = $this->getBroker();

    $response = Password::broker($broker)->sendFirstTimeSetup(
        $this->getSendResetLinkEmailCredentials($request),
        $this->resetEmailBuilder()
    );

    switch ($response) {
        case Password::RESET_LINK_SENT:
            return $this->getSendResetLinkEmailSuccessResponse($response);
        case Password::FIRST_TIME_SETUP:
            return $this->getSendFirstTimeSetupEmailSuccessResponse($response);
        case Password::INVALID_USER:
        default:
            return $this->getSendResetLinkEmailFailureResponse($response);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,同样在AuthController,我们将使另一个函数返回我们的response:

public function getSendFirstTimeSetupEmailSuccessResponse($response) 
{
    return redirect()->back()->with('status', trans($response));
}
Run Code Online (Sandbox Code Playgroud)

最后,如果要覆盖view函数在发送时使用的函数,只需$broker->emailView在调用->sendFirstTimeSetup()函数之前覆盖该属性:

//...

$broker->emailView = "emails.user.first_time_setup";
$response = Password::broker($broker)->sendFirstTimeSetup(
    $this->getSendResetLinkEmailCredentials($request),
    $this->resetEmailBuilder()
);

//...
Run Code Online (Sandbox Code Playgroud)

如果要更改subject电子邮件,请覆盖解雇函数之前的->subject()属性:AuthController->sendFirstTimeSetup()

//...
$this->subject = "First Time User Setup";
$broker->emailView = "emails.user.first_time_setup";
$response = Password::broker($broker)->sendFirstTimeSetup(
    $this->getSendResetLinkEmailCredentials($request),
    $this->resetEmailBuilder()
);

//...
Run Code Online (Sandbox Code Playgroud)

我可以继续下去,但我认为这会让你朝着正确的方向前进.希望它也能帮助其他几个人.