Laravel Auth 为两种用户修改

Posted

技术标签:

【中文标题】Laravel Auth 为两种用户修改【英文标题】:Laravel Auth modify for two kinds of users 【发布时间】:2017-04-15 00:04:29 【问题描述】:

我目前正在尝试修改 laravel Auth 两个能够注册两种不同类型的用户,卖家和买家。两者都具有相同的表单,除了一个字段,只有卖家才有,称为companyName

所以我所做的是放置一个下拉注册而不是普通的注册按钮,这就是我得到的:

<div class="dropdown">
                            <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
                                Registrieren
                                <span class="caret"></span>
                            </button>
                            <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
                            <li>
                                <a href="url('/register/customer')">Als Käufer</a>
                                <a href="url('/register/seller')">Als Händler</a>
                            </li>
                            </ul>
                        </div>

然后我为这两种注册做了一个路由,像这样:

Route::get('/register/userType', 'Auth\RegisterController@showRegistrationForm');

然后我在控制器中简单地重写了这个 showRegistrationForm 函数以将 userType 传递到我的视图中,就像这样:

 public function showRegistrationForm($userType)
    
        return view('auth.register', ['userType'=> $userType]);
    

在我看来,我得到了这个:

@extends('master')

@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Registrieren
                        als <?php if ($userType == 'customer') echo "Käufer";if ($userType == 'seller') echo "Verkäufer";?></div>
                    <div class="panel-body">
                        <form class="form-horizontal" role="form" method="POST" action=" url('/register') ">
                             csrf_field() 

                            <div class="form-group $errors->has('sex') ? ' has-error' : '' ">
                                <label for="sex" class="col-md-4 control-label">Anrede</label>
                                <div class="col-md-6">

                                    <select class="form-control" id="sex">
                                        <option value="male">Herr</option>
                                        <option value="female">Frau</option>
                                </select>
                                </div>

                                @if ($errors->has('sex'))
                                    <span class="help-block">
                                        <strong> $errors->first('sex') </strong>
                                    </span>
                                @endif
                            </div>

                            <div class="form-group $errors->has('name') ? ' has-error' : '' ">
                                <label for="firstName" class="col-md-4 control-label">Vorname</label>

                                <div class="col-md-6">
                                    <input id="firstName" type="text" class="form-control" name="firstName"
                                           value=" old('firstName') " required autofocus>

                                    @if ($errors->has('firstName'))
                                        <span class="help-block">
                                        <strong> $errors->first('firstName') </strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group $errors->has('name') ? ' has-error' : '' ">
                                <label for="name" class="col-md-4 control-label">Nachname</label>

                                <div class="col-md-6">
                                    <input id="name" type="text" class="form-control" name="name"
                                           value=" old('name') " required autofocus>

                                    @if ($errors->has('name'))
                                        <span class="help-block">
                                        <strong> $errors->first('name') </strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <?php if ($userType == 'seller') ?>
                            <div class="form-group $errors->has('companyName') ? ' has-error' : '' ">
                                <label for="companyName" class="col-md-4 control-label">Firmenname</label>

                                <div class="col-md-6">
                                    <input id="companyName" type="text" class="form-control" name="companyName"
                                           value=" old('companyName') " required autofocus>

                                    @if ($errors->has('companyName'))
                                        <span class="help-block">
                                        <strong> $errors->first('companyName') </strong>
                                    </span>
                                    @endif
                                </div>
                            </div>
                            <?php  ?>

                            <div class="form-group $errors->has('email') ? ' has-error' : '' ">
                                <label for="email" class="col-md-4 control-label">E-Mail Addresse</label>

                                <div class="col-md-6">
                                    <input id="email" type="email" class="form-control" name="email"
                                           value=" old('email') " required>

                                    @if ($errors->has('email'))
                                        <span class="help-block">
                                        <strong> $errors->first('email') </strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group $errors->has('password') ? ' has-error' : '' ">
                                <label for="password" class="col-md-4 control-label">Passwort</label>

                                <div class="col-md-6">
                                    <input id="password" type="password" class="form-control" name="password" required>

                                    @if ($errors->has('password'))
                                        <span class="help-block">
                                        <strong> $errors->first('password') </strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group $errors->has('password_confirmation') ? ' has-error' : '' ">
                                <label for="password-confirm" class="col-md-4 control-label">Passwort
                                    wiederholen</label>

                                <div class="col-md-6">
                                    <input id="password-confirm" type="password" class="form-control"
                                           name="password_confirmation" required>

                                    @if ($errors->has('password_confirmation'))
                                        <span class="help-block">
                                        <strong> $errors->first('password_confirmation') </strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div style="display:none;" class="form-group $errors->has('role') ? ' has-error' : '' ">
                                <label for="role" class="col-md-4 control-label">Deine Rolle:</label>

                                <div class="col-md-6">
                                    <input name="role" type="radio"
                                           <?php if ($userType == 'customer') echo "checked";?> value="Käufer">&nbsp;Käufer<br/>
                                    <input name="role" type="radio"
                                           <?php if ($userType == 'seller') echo "checked";?> value="Verkäufer">&nbsp;Verkäufer

                                    @if ($errors->has('role'))
                                        <span class="help-block">
                                        <strong> $errors->first('role') </strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group">
                                <div class="col-md-6 col-md-offset-4">
                                    <button type="submit" class="btn btn-primary">
                                        Registrieren
                                    </button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

所以大部分是基本的,只有几个字段,然后没有修改的 auth 和 companyName 仅在通过路由 /register/seller 访问时显示。

我的RegisterController当然也做了一点修改,尤其是create函数,现在是这样的:

 protected function create(array $data)
    
        $user = User::create([
            'name' => $data['name'],
            'firstName' => $data['firstName'],
            'sex' => $data['sex'],
            'email' => $data['email'],
            'username' => $data['username'],
            'password' => bcrypt($data['password']),
            'role' => $data['role'],
            'templateURL' => ""
        ]);     

        if($data['role'] == 'Verkäufer')
            Complaint::create([
               'user_id' => $user->id,
               'complaintCount' => 0
            ]);
        

        switch($data['role'])
            case 'Käufer':
                $user->attachRole(2);
                break;
            case 'Verkäufer':
                $user->attachRole(3);
                $user->companyName = $data['companyName'];
                $user->save();
                break;
            default:
                $user->attachRole(2);
                break;
        


        return $user;
    

现在问题来了:如您所见,在我的“个人”视图中,无论如何这基本上只是一个,我仍然发布到 url /register,我认为这应该可以工作,但它没有。 ...任何想法为什么这不起作用?我也尝试添加单独的路线,所以是这样的:

Route::post('/register/seller', 'Auth\RegisterController@create');
Route::post('/register/buyer', 'Auth\RegisterController@create');

但那也不好用。在这两种情况下,我只是返回相同的窗口,就好像有错误一样(所以我的数据仍然输入(期望密码),但没有在数据库中注册或输入任何内容,但也没有出现错误,在我看来,也不在控制台中。

有趣的是网络选项卡,它似乎明确地将请求发送到/register,因为它显示在那里,状态码为 302,但还有路由 /register/customer,我想知道为什么......还有什么有趣的是,我认为它有点工作,好像我输入的密码少于 6 个字符或 2 个不同的密码,我得到一个错误,所以表格似乎以某种方式发布,但什么都不是进入数据库....

任何想法为什么会发生这种情况以及问题是什么?

【问题讨论】:

对于这样的用例......我更喜欢构建自己的 AuthController...... @prateekkathal 你的意思是你自己的RegisterController?它会改变什么?... 首先,您可以控制您希望如何将内容保存在数据库中。其次,您将控制要遵循的路线和目的。 :) 你能给我一个例子来说明如何实现这样一个控制器以及如何使用我的而不是默认的 你能告诉我你的表/关系是如何创建的吗? 【参考方案1】:

首先,我想向您推荐一种多态方法来拯救用户。现在,您只有 2 种用户类型,如果您有第三种用户类型(比如零售商或批发商或等等等等)怎么办……对于每个人,您将需要不同的字段,这些字段可能适合也可能不适合所有人用户类型...

那么,就这样吧

class User

  public function profile()
  
    return $this->morphTo();
  


class Seller

  public function user()
  
    return $this->morphOne('App\User', 'profile');
  


class Buyer

  public function user()
  
    return $this->morphOne('App\User', 'profile');
  

现在,在您的路线中,添加这些

Route::get('login', 'LoginController@show')->name('login.show');
Route::post('login', 'LoginController@login')->name('login.post');

Route::get('register', 'RegisterController@show')->name('register.show');
Route::post('register', 'RegisterController@register')->name('register.post');

Route::get('logout', 'LoginController@logout')->name('login.logout');

现在,在您的表单中添加一个下拉/单选按钮以供选择用户类型(您也可以单独运行不同的路线并隐藏这些字段);

说,

<select name="type">
  <option value="1">Buyer</option>
  <option value="2">Seller</option>
<select>

你的RegisterController@register可以如下:

use App\Buyer;
use App\Seller;
use Validator;

class RegisterController extends Controller

  public function show()
  
    return view('auth.register');
  

  public function register()
  
    $inputs = request()->all();

    $validator = $this->validator($inputs);

    if($validator->fails()) 
      return redirect()->back()->withErrors($validator)->withInput();
    

    $userInputs = array_only($inputs, ['name', 'email', 'password']);
    $userInputs['password'] = Hash::make($userInputs['password']);

    switch($inputs['type'])
    
      case 1:
        $sellerInputs = array_only($inputs, ['company_name']);

        $seller = Seller::create();
        $user = $seller->user()->create($userInputs);
      case 2: 
        $buyer = Buyer::create();
        $user = $buyer->user()->create($userInputs);
      default:
        $user = null;
        break;
    

    if(!$user) 
      return redirect()->back(); //Show flash messsage etc... and redirect back to show an error
    

    auth()->attempt(array_only($inputs, ['email', 'password']));
    return redirect(route('some.route'));
  

  protected validator($inputs)
  
    $rules = [
      'name' => 'required|min:1|max:50',
      'email' => 'required|email|min:1|max:100',
      'password' => 'required|min:6|max:25',
      // Other rules
    ];

    $messages = [
      // Any special messages if required...
    ];

    return Validator::make($inputs, $rules, $messages);
  

在LoginController中使用相同的编码结构...我只是在下面写登录后面的登录

public function login()

  $inputs = request()->all();

  //Validator etc...

  if(auth()->attempt(array_only($inputs, ['email', 'password']))) 
    return redirect(route('some.route'));
   else 
    return redirect()->back(); // Again... Show some error flash message
  

注意:-我还没有测试过代码,但我有 99% 的把握这应该可以工作......我自己写下了所有这些......几乎花了半个小时! p>

希望一切都得到解答并且您理解。如果您有任何其他疑问,请在下面的 cmets 中告诉我 :)

【讨论】:

首先,感谢您的回答:) 我有几个问题: 1. 这个多态的东西到底是做什么的?到目前为止,只与belongsTohasOnehasMany 一起工作,上面的代码究竟做了什么?然后是路线:我想我会坚持我拥有的东西,所以有两种不同的注册路线,一种用于卖家,一种用于买家,但这应该可以创建这些路线。还有最后一个问题:ForgotPasswordControllerResetPasswordController 是否仍然有效,还是我还必须重写它们? 又是多态的东西,我是否必须为每种用户类型创建一个模型,或者这将如何进行? @nameless 请阅读多态关系here。最后,ForgotPasswordController 和 ResetPasswordController 仍然可以工作,不过你必须添加它们的路由...... :)

以上是关于Laravel Auth 为两种用户修改的主要内容,如果未能解决你的问题,请参考以下文章

Larave中CSRF攻击

laravel策略类,实现当前登陆的用户是否具有删除,修改文章的权限

Laravel Socialite 回调 auth('customer')->user() 为 null

Laravel 过滤路由

Laravel 在身份验证异常时自动重定向

Laravel 修改 Auth::user() 查询?