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

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

@[Laraval|后端|框架]


  • LaravelWeb开发实战之路八
    • 前言
    • 会话
      • 会话控制器
      • 登录表单
      • 用户身份认证
      • 登录提示和重定向
    • 用户登录
    • 注册后自动登录
    • 用户退出
    • 记住我

前言

完成了注册,接下来要做的就登录和退出登录了
一般用户的登录流程如下:
- 访问登录页面,输入账号密码点击登录;
- 服务器对用户身份进行认证,认证通过后,记录登录状态并进行页面重定向;
- 登录成功后的用户,能够使用退出按钮来销毁当前登录状态;

最后,为了用户的体验,加上记住我,免得再次登录麻烦,是最好不过了

会话

由于HTTP协议的无状态性,想同步两个页面的用户信息,我们需要借助会话在浏览器内存储身份信息

会话控制器

与之前一样,要么直接拷贝控制器基本内容避免命令行操作,否则就使用命令php artisan make::controller SessionsController生成,相信大家一定很熟悉了。

接下来,我们还需要配置对应的路由,稍微分析一下,路由的功能有显示登录页面,创建新的session,退出时销毁会话,也就是:

HTTP请求 URL 动作 作用
GET /login SessionsController@create 显示登录页面
POST /login SessionsController@store 创建新会话(登录)
DELETE /logout SessionsController@destroy 销毁会话(退出登录)

转换成代码也就是在`route/web.php加入代码

Route::get('login', 'SessionsController@create')->name('login');
Route::post('login', 'SessionsController@store')->name('login');
Route::delete('logout', 'SessionsController@destroy')->name('logout');

登录表单

在控制器app/Http/Controllers/SessionsController.php内加入create动作



namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;

class SessionsController extends Controller
{
    public function create()
    {
        return view('sessions.create');
    }
}

对应的,我们需要创建一个登录页面,在resources/views/sessions/create.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')

      <form method="POST" action="{{ route('login') }}">
          {{ csrf_field() }}

          <div class="form-group">
            <label for="email">邮箱:label>
            <input type="text" name="email" class="form-control" value="{{ old('email') }}">
          div>

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

          <button type="submit" class="btn btn-primary">登录button>
      form>

      <hr>

      <p>还没账号?<a href="{{ route('signup') }}">现在注册!a>p>
    div>
  div>
div>
@stop

用户身份认证

为了创建认证,我们需要在会话控制器内添加store方法啦进行验证

    public function store(Request $request)
    {
       $credentials = $this->validate($request, [
           'email' => 'required|email|max:255',
           'password' => 'required'
       ]);

       return;
    }

但这显然不够,这段代码里只是进行了输入验证,并未要求邮箱和对应密码的匹配性

通过Auth的attempt方法,我们可以快速完成验证

if (Auth::attempt(['email' => $email, 'password' => $password])) {
    // 该用户存在于数据库,且邮箱和密码相符合
}

attempt 方法执行的代码逻辑如下:
使用 email 字段的值在数据库中查找;
如果用户被找到:
- 先将传参的 password 值进行哈希加密,然后与数据库中 password 字段中已加密的密码进行匹配;
- 如果匹配后两个值完全一致,会创建一个『会话』给通过认证的用户。会话在创建的同时,也会种下一个名为 laravel_session 的 HTTP Cookie,以此 Cookie 来记录用户登录状态,最终返回 true;
- 如果匹配后两个值不一致,则返回 false;
如果用户未找到,则返回 false。

故还需在return前加入代码

if (Auth::attempt($credentials)) {
           // 登录成功后的相关操作
       } else {
           // 登录失败后的相关操作
       }

登录提示和重定向

接下来我们还需要添加认证通过和失败对应的操作

当认证失败时,我们使用danger来提示用户

session()->flash('danger', '很抱歉,您的邮箱和密码不匹配');

成功时,我们要重定向到用户页面
所以逻辑就变成

 if (Auth::attempt($credentials)) {
           session()->flash('success', '欢迎回来!');
           return redirect()->route('users.show', [Auth::user()]);
       } else {
           session()->flash('danger', '很抱歉,您的邮箱和密码不匹配');
           return redirect()->back();
       }

注意:在使用Auth前,一定要加上一句use Auth;

用户登录

由于添加了用户登录,从网页交互来看,我们也要修改一下导航栏,把已登录和未登录区别开来

小贴士:Laravel 提供了 Auth::check() 方法用于判断当前用户是否已登录,已登录返回 true,未登录返回 false

修改一下header,加上逻辑

<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 Appa>
      <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="#">编辑资料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>

注意,在这里使用了bootstrap的下拉菜单,所以要把jQuery和boostrap.js文件包含进去,不然下拉菜单就没法用啦

在这里要关注一下退出的代码

<form action="{{ route('logout') }}" method="POST">
  {{ csrf_field() }}
  {{ method_field('DELETE') }}
  <button class="btn btn-block btn-danger" type="submit" name="button">退出button>
form>

其实是一个表单,触发了DELETE

注册后自动登录

添加这个功能后,体验会更好

我们修改用户的store方法
在刷新前加入

 Auth::login($user);

即可

用户退出

我们通过laravel自带的Auth::logout()实现退出

加上destroy方法

class SessionsController extends Controller
{
    .
    .
    .
    public function destroy()
    {
        Auth::logout();
        session()->flash('success', '您已成功退出!');
        return redirect('login');
    }
}

记住我

在 Laravel 的默认配置中,如果用户登录后没有使用『记住我』功能,则登录状态默认只会被记住两个小时。如果使用了『记住我』功能,则登录状态会被延长到五年
首先,在登录页上加上记住我的复选框

<div class="checkbox">
            <label><input type="checkbox" name="remember"> 记住我label>
          div>

Auth::attempt() 方法可接收两个参数,第一个参数为需要进行用户身份认证的数组,第二个参数为是否为用户开启『记住我』功能的布尔值。接下来让我们修改会话控制器中的 store 方法,为 Auth::attempt() 添加『记住我』参数

if (Auth::attempt($credentials, $request->has('remember'))) {
           session()->flash('success', '欢迎回来!');
           return redirect()->route('users.show', [Auth::user()]);
       } else {
           session()->flash('danger', '很抱歉,您的邮箱和密码不匹配');
           return redirect()->back();
       }

你可能感兴趣的:(团队项目,框架,后端,教程)