Laravel——Web开发实战之路(九)

21 篇文章 1 订阅
10 篇文章 0 订阅

Laravel——Web开发实战之路(九)

@[Laraval|后端|框架]


前言

之前已经完成了用户的注册,登录,退出等功能,接下来要做的就是用户的操作了,类似于编辑资料等等

编辑表单

由于之前我们已经用resourse方法为用户添加了完整的动作,所以我们不需要再添加编辑界面的路由

Route::get('/users/{user}/edit', 'UsersController@edit')->name('users.edit');

在用户控制器加入编辑用户的操作

public function edit(User $user)
    {
        return view('users.edit', compact('user'));
    }

执行了以下操作
- 利用了 Laravel 的『隐性路由模型绑定』功能,直接读取对应 ID 的用户实例 user u s e r , 未 找 到 则 报 错 ; − 将 查 找 到 的 用 户 实 例 user 与编辑视图进行绑定

接下来,只要为用户添加 resources/views/users/edit.blade.php即可

@extends('layouts.default')
@section('title', '更新个人资料')

@section('content')
<div class="col-md-offset-2 col-md-8">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h5>更新个人资料</h5>
    </div>
      <div class="panel-body">

        @include('shared._errors')

        <div class="gravatar_edit">
          <a href="http://gravatar.com/emails" target="_blank">
            <img src="{{ $user->gravatar('200') }}" alt="{{ $user->name }}" class="gravatar"/>
          </a>
        </div>

        <form method="POST" action="{{ route('users.update', $user->id )}}">
            {{ method_field('PATCH') }}
            {{ csrf_field() }}

            <div class="form-group">
              <label for="name">名称:</label>
              <input type="text" name="name" class="form-control" value="{{ $user->name }}">
            </div>

            <div class="form-group">
              <label for="email">邮箱:</label>
              <input type="text" name="email" class="form-control" value="{{ $user->email }}" disabled>
            </div>

            <div class="form-group">
              <label for="password">密码:</label>
              <input type="password" name="password" class="form-control" value="{{ old('password') }}">
            </div>

            <div class="form-group">
              <label for="password_confirmation">确认密码:</label>
              <input type="password" name="password_confirmation" class="form-control" value="{{ old('password_confirmation') }}">
            </div>

            <button type="submit" class="btn btn-primary">更新</button>
        </form>
    </div>
  </div>
</div>
@stop

同时添加样式

.gravatar_edit {
  margin: 15px auto;
  text-align: center;
}

 gravatar_edit.gravatar {
    float: none;
    max-width: 100px;
  }

最后,我们还要在导航栏中添加入口
resources/views/layouts/_header.blade.php

<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <div class="col-md-offset-1 col-md-10">
      <a href="/" id="logo">Sample App</a>
      <nav>
        <ul class="nav navbar-nav navbar-right">
          @if (Auth::check())
            <li><a href="#">用户列表</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                {{ Auth::user()->name }} <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
                <li><a href="{{ route('users.show', Auth::user()->id) }}">个人中心</a></li>
                <li><a href="{{ route('users.edit', Auth::user()->id) }}">编辑资料</a></li>
                <li class="divider"></li>
                <li>
                  <a id="logout" href="#">
                    <form action="{{ route('logout') }}" method="POST">
                      {{ csrf_field() }}
                      {{ method_field('DELETE') }}
                      <button class="btn btn-block btn-danger" type="submit" name="button">退出</button>
                    </form>
                  </a>
                </li>
              </ul>
            </li>
          @else
            <li><a href="{{ route('help') }}">帮助</a></li>
            <li><a href="{{ route('login') }}">登录</a></li>
          @endif
        </ul>
      </nav>
    </div>
  </div>
</header>

编辑失败

提交后,我们还需要用用户控制器的update方法及时处理提交的消息

public function update(User $user, Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:50',
            'password' => 'required|confirmed|min:6'
        ]);

        $user->update([
            'name' => $request->name,
            'password' => bcrypt($request->password),
        ]);

        return redirect()->route('users.show', $user->id);
    }

一开始验证提交的 内容。在进行更新操作,最后重定向到个人页面

编辑成功

成功自然要提示一波啦,所以对逻辑稍稍进行优化

 public function update(User $user, Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:50',
            'password' => 'nullable|confirmed|min:6'
        ]);

        $data = [];
        $data['name'] = $request->name;
        if ($request->password) {
            $data['password'] = bcrypt($request->password);
        }
        $user->update($data);

        session()->flash('success', '个人资料更新成功!');

        return redirect()->route('users.show', $user->id);
    }

权限系统

现在虽然可以登录和注册,但是明显还存在两个安全漏洞
- 未登录用户可以访问 edit 和 update 动作
- 登录用户可以更新其它用户的个人信息

因为这两个动作都未和用户自己绑定

检验登录

Laravel 中间件 (Middleware) 为我们提供了一种非常棒的过滤机制来过滤进入应用的 HTTP 请求,例如,当我们使用 Auth 中间件来验证用户的身份时,如果用户未通过身份验证,则 Auth 中间件会把用户重定向到登录页面。如果用户通过了身份验证,则 Auth 中间件会通过此请求并接着往下执行。Laravel 框架默认为我们内置了一些中间件,例如身份验证、CSRF 保护等

使用Auth过滤用户动作

public function __construct()
    {
        $this->middleware('auth', [            
            'except' => ['show', 'create', 'store']
        ]);
    }

__construct是构造方法,希望show,create,store直接执行,过滤edit等

Laravel 提供的 Auth 中间件在过滤指定动作时,如该用户未通过身份验证(未登录用户),默认将会被重定向到 /login 登录页面

用户只能编辑自己的资料

Laravel使用授权策略对操作权限进行检测
首先,使用php artisan make:policy UserPolicy生成授权策略文件
app/Policies/UserPolicy.php

<?php

namespace App\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;
use App\Models\User;

class UserPolicy
{
    use HandlesAuthorization;

    public function update(User $currentUser, User $user)
    {
        return $currentUser->id === $user->id;
    }
}

update 方法接收两个参数,第一个参数默认为当前登录用户实例,第二个参数则为要进行授权的用户实例。当两个 id 相同时,则代表两个用户是相同用户,用户通过授权,可以接着进行下一个操作。如果 id 不相同的话,将抛出 403 异常信息来拒绝访问

然后在AuthServiceProvider 类中对授权策略进行设置

 protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        \App\Models\User::class  => \App\Policies\UserPolicy::class,
    ];

在用户控制器添加Authorize方法进行检验

$this->authorize('update', $user);

剩下的完全无坑,一路按照书走就ok了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值