※ 2018/10/09 Laravel5.6 から 5.7 に記述を更新
Laravelに登録しているユーザでログイン処理をして、vue画面に連携してみます
環境設定他関連記事はこちら
Laravel + Vue + Vuetify で業務サイト作ってみる
社内サイトなどでユーザ登録をオープンにしない想定で、
パスワード忘れとかも会社の人に連絡してパスワード再発行してもらうため
「ユーザ登録」や「パスワード再設定」系は利用しません
さらに一般公開するページはないのでログイン必須にしときます
#1.事前DB設定(MySQL8を利用)
専用DBを作成して、DBユーザとパスワードを設定
$ mysql -u root -p
mysql> CREATE DATABASE lara;
mysql> CREATE USER lara_user@localhost IDENTIFIED WITH mysql_native_password BY 'lara_pass';
mysql> GRANT ALL PRIVILEGES on lara.* to lara_user@localhost;
mysql> quit
設定した後はログイン確認しときます
$ mysql -u lara_user -p lara
Enter password:
#2.事前Laravel設定(DB接続設定)
上記手順で作成したDBとDBユーザの設定を入れときます
~~
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=lara
DB_USERNAME=lara_user
DB_PASSWORD=lara_pass
~~~
#3.Laravel認証の有効化
$ php artisan make:auth
作成されたファイルを確認
$ find ./app ./resources -type f | grep -i auth
./app/Http/Controllers/Auth/ForgotPasswordController.php
./app/Http/Controllers/Auth/LoginController.php
./app/Http/Controllers/Auth/RegisterController.php
./app/Http/Controllers/Auth/ResetPasswordController.php
./app/Http/Controllers/Auth/VerificationController.php
./app/Http/Middleware/Authenticate.php
./app/Http/Middleware/RedirectIfAuthenticated.php
./app/Providers/AuthServiceProvider.php
./resources/lang/en/auth.php
./resources/views/auth/passwords/email.blade.php
./resources/views/auth/passwords/reset.blade.php
./resources/views/auth/login.blade.php
./resources/views/auth/register.blade.php
./resources/views/auth/verify.blade.php
$ find ./database/ -type f -name "*.php"
./database/factories/UserFactory.php
./database/migrations/2014_10_12_000000_create_users_table.php
./database/migrations/2014_10_12_100000_create_password_resets_table.php
./database/seeds/DatabaseSeeder.php
#4.標準のユーザテーブルをちょっと修正
標準だと email でのログインのところを loginID でのログインに変えるためにちょっと修正
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('loginid')->unique()->comment('ログインID');
// $table->string('email')->unique();
// $table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
email のカラムを loginid に変更
Lravel5.7で追加されたメールアドレスの検証カラムは使わないので削除
###テーブルを変更したので、モデルも修正
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
// 'email',
'loginid',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
#5.ユーザテーブルの初期データ登録設定
有効なユーザデータと、後で一覧表示するための試験用ダミーデータも100件ほど作成しときます
###まずは seedを実行するように設定
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
★ $this->call(UsersTableSeeder::class);
}
}
★コメントアウトになっている部分を有効化しておきます
###次にどんなデータを作るかを定義
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
★1 DB::table('users')->insert(
[
[
'name' => 'メイプル ノブ',
'loginid' => 'maple_nobu',
'password' => Hash::make('password'),
]
]);
★2 factory(App\User::class, 100)->create();
}
}
★1 とりあえず1レコードだけ任意データを登録
★2 ダミーデータを 100レコード作成
###ダミーデータの作り方を定義
<?php
use Faker\Generator as Faker;
use Illuminate\Support\Facades\Hash;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
★ 'loginid' => $faker->unique()->safeEmail,
'password' => Hash::make('password'),
'remember_token' => str_random(10),
];
});
★ ダミーデータの作成設定
※ loginidはここでは メールアドレスにしときます
※ パスワードは Hash でデフォルト”password" に設定しときます
#6.ユーザテーブルの初期データ登録実行
$ composer dump-autoload
※とりあえず新規作成した UsersTableSeeder.php とかを読み込ませとく
やっとかないと
ReflectionException : Class UsersTableSeeder does not exist
とか言われる
ユーザ作成
$ php artisan migrate:refresh --seed
Migration table not found.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
Seeding: UsersTableSeeder
###作成確認
テーブルとデータの作成を確認
$ mysql -u lara_user -p lara
Enter password:
mysql> show tables;
+-----------------+
| Tables_in_lara |
+-----------------+
| migrations |
| password_resets |
| users |
+-----------------+
3 rows in set (0.00 sec)
mysql> desc users;
+----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| loginid | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| remember_token | varchar(100) | YES | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+----------------+------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
mysql> select name, loginid from users;
+--------------------------+----------------------------------+
| name | loginid |
+--------------------------+----------------------------------+
| メイプル ノブ | maple_nobu |
| Ara Pollich | diego.kling@example.com |
| Jess Little | mschimmel@example.com |
| Prof. Kira Parisian | gerry57@example.com |
~~~~
| Stanton Skiles Sr. | cschmeler@example.org |
| Miss Amiya Rosenbaum PhD | keon75@example.org |
| Danyka Lakin | reilly.percival@example.org |
| Prof. Devan Skiles | mackenzie.rutherford@example.com |
+--------------------------+----------------------------------+
101 rows in set (0.01 sec)
mysql>
テーブルもデータもできてるけど、、外人名になってる
日本語設定入れてやり直し
~~~~
★1 'locale' => 'jp',
~~~~
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Faker Setting
|--------------------------------------------------------------------------
*/
★2 'faker_locale' => env('DEV_FAKER_LOCALE', 'ja_JP'),
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
~~~~
★1 全体の言語設定
★2 faker の言語を日本語に設定
###ユーザ再作成
$ php artisan migrate:refresh --seed
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_100000_create_password_resets_table
Rolling back: 2014_10_12_000000_create_users_table
Rolled back: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
Seeding: UsersTableSeeder
###再度作成確認
$ mysql -u lara_user -p lara
Enter password:
mysql> select name, loginid from users;
+-----------------------+-------------------------------+
| name | loginid |
+-----------------------+-------------------------------+
| メイプル ノブ | maple_nobu |
| 高橋 京助 | wmatsumoto@example.org |
| 吉田 真綾 | kimura.yuta@example.com |
~~~~
| 吉田 洋介 | asuka.nomura@example.com |
| 大垣 翼 | naoki72@example.org |
| 渚 治 | jwatanabe@example.net |
+-----------------------+-------------------------------+
101 rows in set (0.00 sec)
日本語になった
#7.ログインで loginID を利用するように修正
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
★ public function username()
{
★ return 'loginid';
}
}
どう修正するかというと、まずLaravelの本体からログイン時に使うカラムを設定しているところを探します
どこを探すかといえば、最初に宣言している「use Illuminate\Foundation\Auth\AuthenticatesUsers;」の本体ファイル
vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php
このファイルのユーザ名を設定している個所を探して、コピー
「 LoginController.php 」に張り付けして、ログイン時に使うカラムを変更して上書きして修正します。
#8.ユーザ登録などいろいろ閉鎖
標準の route 設定を見てみると
$ php artisan route:list
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | home | home | App\Http\Controllers\HomeController@index | web,auth |
| | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web,guest |
| | POST | login | | App\Http\Controllers\Auth\LoginController@login | web,guest |
| | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web |
| | POST | password/email | password.email | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail | web,guest |
| | GET|HEAD | password/reset | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest |
| | POST | password/reset | password.update | App\Http\Controllers\Auth\ResetPasswordController@reset | web,guest |
| | GET|HEAD | password/reset/{token} | password.reset | App\Http\Controllers\Auth\ResetPasswordController@showResetForm | web,guest |
| | GET|HEAD | register | register | App\Http\Controllers\Auth\RegisterController@showRegistrationForm | web,guest |
| | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web,guest |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
いっぱい登録されてるので、いろいろ閉鎖
必要なものだけを設定
ついでにログインしないで公開するページはないのでログインを必須に設定
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('home');
})->middleware('auth'); ★1
//Auth::routes(); ★2
★3
Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('/login', 'Auth\LoginController@login');
Route::post('/logout', 'Auth\LoginController@logout')->name('logout');
Route::get('/home', 'HomeController@index')->name('home');
★1 ログイン必須
★2 標準の設定はコメントアウト
★3 login、logout のみを有効化
###設定確認
$ php artisan route:list
+--------+----------+----------+--------+---------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------+--------+---------------------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web,auth |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | home | home | App\Http\Controllers\HomeController@index | web,auth |
| | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web,guest |
| | POST | login | | App\Http\Controllers\Auth\LoginController@login | web,guest |
| | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web |
+--------+----------+----------+--------+---------------------------------------------------------+--------------+
すっきりした
#9.ログインフォームとかいろいろ修正
ユーザ登録とかパスワード忘れとかのroute設定が残ってるとエラーになるので削除
まずはページの基礎部分を修正
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Fonts -->
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
<nav class="navbar navbar-expand-md navbar-light navbar-laravel">
<div class="container">
<a class="navbar-brand" href="{{ url('/') }}">
{{ config('app.name', 'Laravel') }}
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar -->
<ul class="navbar-nav mr-auto">
</ul>
<!-- Right Side Of Navbar -->
<ul class="navbar-nav ml-auto">
<!-- Authentication Links -->
@guest
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
</li>
<!-- ★ <li class="nav-item">
@if (Route::has('register'))
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
@endif
</li>
-->
@else
<li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }} <span class="caret"></span>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
@csrf
</form>
</div>
</li>
@endguest
</ul>
</div>
</div>
</nav>
<main class="py-4">
@yield('content')
</main>
</div>
</body>
</html>
★ ユーザ登録部分をコメントアウト
次にログイン部分を修正
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group row">
<!-- ★1
<label for="email" class="col-sm-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
-->
<label for="loginid" class="col-sm-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="loginid" type="text" class="form-control{{ $errors->has('loginid') ? ' is-invalid' : '' }}" name="loginid" value="{{ old('loginid') }}" required autofocus>
@if ($errors->has('loginid'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('loginid') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
@if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
<?php /* ★2
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
*/
?>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
★1 email の部分を loginid に変更
★2 パスワード忘れは削除(htmlのコメントアウトではrouteエラーになるのでPHPコメントにしてます)
###ログイン後の部分に「ログアウト」を追加しとく
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel5.7 + Vue.js2.5</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">
<!-- Styles -->
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
<style>
html, body {
background-color: #fff;
color: #636b6f;
font-family: 'Nunito', sans-serif;
font-weight: 200;
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<div id="app">
<example-component test="GET DATA: {{ $_GET['AAA'] }}" logout="{{ route('logout') }}"></example-component>
</div>
<script src=" {{ mix('js/app.js') }} "></script>
</body>
</html>
ログイン後の vue 画面に「logout="{{ route('logout') }}"」としてログアウト時に呼び出すルートを渡しておく
vue側にログアウトボタンを追加
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card card-default">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component. <br>
<span class="test">{{ test }}</span>
<br>
<button v-on:click="axiosLogout">logout</button>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.test {
color: red;
}
</style>
<script>
export default {
props: {
test: String,
logout: String,
},
mounted() {
console.log('ExampleComponent mounted.')
},
methods: {
axiosLogout() {
axios.post(this.logout)
.then( function (response) {
console.log(response)
}.bind(this))
.catch(function (error) {
console.log(error)
if (error.response) {
if (error.response.status) {
if (error.response.status == 401 || error.response.status == 419) {
var parser = new URL(this.logout)
location.href=parser.origin
}
}
}
}.bind(this))
},
},
}
</script>
logout は POST として route 設定しているので axios で要求を投げるようにしときます
タイムアウトしたりすると 419 が返るらしいのでとりあえず追記してみたけど。。この部分ちゃんと動くかは未検証です
vue側を変えたのでコンパイルもしておく
$ npm run dev
DONE Compiled successfully in 5671ms 16:05:32
Asset Size Chunks Chunk Names
/js/app.js 1.39 MB 0 [emitted] [big] /js/app
/css/app.css 198 kB 0 [emitted] /js/app
#10.Laravel ログイン
Laravel を起動して
$ php artisan serve --host=172.16.0.100 --port=8000
ブラウザでアクセスすると
http://172.16.0.100:8000/?AAA=12345_67890
↓↓
ログインページへ飛ばされて
http://172.16.0.100:8000/login
↓↓
ちゃんとログインしたら
http://172.16.0.100:8000/?AAA=12345_67890
GETに指定した文字列とともにページが表示されること
ログアウトボタンも動作すること
(ログアウトして、ログイン画面が表示されること)
以上
今回もソースはこちら
https://github.com/u9m31/u9m31/tree/step02