2015年8月30日日曜日

Laravel標準の認証機能を利用していてハマる

Laravel標準の認証機能でユーザ追加やログインの処理が出来るのは分かったが、認証された状態では/homeにリダイレクトされてしまい困る。

ここにリダイレクトする輩は、
  • ¥Illuminate¥Foundation¥Auth¥RedirectsUsers@redirectPath
  • ¥Illuminate¥Foundation¥Auth¥ResetsPasswords@redirectPath
  • app¥Http¥Middleware¥RedirectIfAuthenticated@handle
のお三方である。

最初の二つは、ユーザ認証・登録やパスワードリセットの操作の時のみに発動するっぽいので、最後のが怪しい。で、このクラスを呼んでいるファイルを調べると、app¥Http¥Kernelであった。$routeMiddlewareという変数にこのクラスが設定されている。何のことかと言うと、

Laravel 5 の Global Middleware ではルートの名前がとれない?

なるほど、「特定のルートに割り当てる Middleware」のことのようだ。そして、その解釈からすると、このクラスは guestという特定のルートに割り当てられている様だ。

(続く)

2015年8月16日日曜日

Laravel5標準の認証機能

ログインに成功すると/homeというパスにリダイレクトされる。

これは、RedirectsUsersトレイトのredirectPathメソッドにハードコードされている。

但し、上記メソッド内の実装の通り、下記のプロパティを順番に調べて、プロパティが存在すればそちらを代わりに返す事になっている。
  1. redirectPath
  2. redirectTo
なるほどね。

この場合、最終的に RedirectsUsersトレイトの実装を使っているクラスはAuthControllerなので、こちらに上記のプロパティどちらかを実装して値を設定すれば、ログイン後のリダイレクト先を/homeから変更出来るというわけ。

ちなみに、調べてみると両者は下記のクラスのredirectPathメソッド内 で参照されている。
  • Illuminate/Foundation/Auth/RedirectsUsers.php
  • Illuminate/Foundation/Auth/ResetsPasswords.php
で、なんで二つあるんだろうと思ったのだが、過去のLaravelの更新履歴を見ると、どうやらredirectPathが正しく、redirectToは歴史的な理由(もしくは、過去のLaravelを使っているコードとの互換性の関係)で残されているっぽい。

When to set redirectPath property in Laravel 5 auth trait

なるほどね〜。ソースを見ると色々な事が分かりますな。

Homesteadのmysql

HomesteadのMySQLにログインする時は、HomesteadのVM上で下記のコマンドを打つ。

% mysql -u root -psecret homestead

あとはSHOW TABLESするなりお好きに。

2015年8月15日土曜日

LaravelとPHPのトレイト(Trait)とView周り色々

最近のPHPにはトレイト(Trait)という機能がある。初めて知った。

PHP: トレイト - Manual

要は、多重継承出来ない PHPで、実装をうまく再利用する為の機能らしい。私はC++で多重継承の経験があるけれど、確かにあれはとっちらかってワケが分からなくなるので、単一継承の方が良いと思う(Javaが単一継承を選んだ時もそう思った)が、実装を再利用するにはちょっと不便なのも事実。

PHPのトレイトでは、メソッドだけで無くプロパティも設定出来たり、抽象メソッドも設定出来たりする。殆ど実体化(instantiate)出来ないだけのクラスって感じだな。

クラス内でトレイトを指定すると、現クラスの実装→トレイトの実装→親クラスの実装、という順番で優先順位が設定され実装がオーバーライドされる。

で、例えばLaravelのAuthControllerAuthenticatesAndRegistersUsersトレイトを使っている。このAuthenticatesAndRegistersUsersトレイトは、AuthenticatesUsersトレイトとRegistersUsersトレイトを使っている。このAuthenticatesUsersトレイトが、例えばgetLogin, postLogin, getLogout等のメソッドの実装を持っている。

getLoginの実装ではauth.authenticateというViewがあればそれを、無ければauth.loginというViewを返す。このauth.loginというViewの名前は、自動的にプロジェクト内の/resources/views/auth/login.blade.phpというパスに変換され、該当するファイルを表示する。

HTML Formの表示には、Laravel5ではオプションになったHTMLヘルパを使う事が出来る。

Laravel5で新規データの作成

HTMLタグで書く事も出来るが、ヘルパを使うメリットとしては、HTMLタグにPHPコードを埋め込む際にタイプ(文字)数が減るとか、そういうメリットがあるというところか。

2015年7月26日日曜日

Homestead上でLaravelアプリを開発するにあたって始め方がよう分からん

Homesteadをインストールしたは良いが、その後アプリを開発しようにもLaravelのファイルが無い。色々とググってみたが良く分からない。

そこで、HomesteadにログインしてcomposerでLaravelのプロジェクトを作成してみる事に。

% composer create-project laravel/laravel --prefer-dist <project name>
...(省略)...

そして、ホスト環境と共有されているフォルダにごっそりファイルをコピーする。

% cd ~/<project name>/
% cp -R .[a-z]* * ../Code/Laravel/

これでHomestead環境にHTTPアクセスすると、ちゃんとindex.phpが表示された。

しかし、何となくこの手順はキモいのだけれど、本当はどうやるべきなのか。

<追記>
しかし、とりあえずこれでLaravelエキスパート養成読本[モダンな開発を実現するPHPフレームワーク!]のチュートリアルで遊べる事が分かった。Laravel凄い。

Homesteadにログインする

ホスト環境(私の場合Mac)とフォルダが共有されているのは分かっていたが、シェルでログインするにはどうしたら良いのだろうかと調べてみるとこれがまた簡単。Vagrantって本当に凄いな。

vagrant sshと打てば良いらしい。

% vagrant ssh 
A Vagrant environment or target machine is required to run this
command. Run `vagrant init` to create a new Vagrant environment. Or,
get an ID of a target machine from `vagrant global-status` to run
this command on. A final option is to change to a directory with a
Vagrantfile and to try again.


なるほど、vagrant global-statusで取得したIDを指定しないといけないのね。

% vagrant global-status 
id       name    provider   state   directory                          
------------------------------------------------------------------------
884a4c3  default virtualbox running /Users/<username>/Homestead              

The above shows information about all known Vagrant environments
on this machine. This data is cached and may not be completely
up-to-date. To interact with any of the machines, you can go to
that directory and run Vagrant, or you can use the ID directly
with Vagrant commands from any directory. For example:
"vagrant destroy 1a2b3c4d"


なるほど、これか。早速指定してみる。


% vagrant ssh 884a4c3 
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-24-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
Last login: Tue Oct 21 14:52:42 2014 from 10.0.2.2

vagrant@homestead:~%

おお。これだけでログイン出来てしまった。凄い便利だな。

Homesteadをインストールする

まず、VirtualBoxをインストール。MacOS向けのインストーラをここからダウンロードして実行するだけ。簡単。

次にVagrantをインストール。公式WebサイトのダウンロードページからMacOS向けのインストーラをダウンロードして実行するだけ。これも簡単。

% which vagrant/usr/local/bin/vagrant

なるほど、無事インストールされた模様。そこで更にHomesteadのインストール手順に従うと、、、

% vagrant box add laravel/homestead==> box: Loading metadata for box 'laravel/homestead'
    box: URL: https://atlas.hashicorp.com/laravel/homestead
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) virtualbox
2) vmware_desktop

Enter your choice: 1
==> box: Adding box 'laravel/homestead' (v0.2.7) for provider: virtualbox
    box: Downloading: https://atlas.hashicorp.com/laravel/boxes/homestead/versions/0.2.7/providers/virtualbox.box

==> box: Successfully added box 'laravel/homestead' (v0.2.7) for 'virtualbox'!

このダウンロードに結構時間が掛かる。大体1時間半くらいかかった。更にHomesteadをgit cloneする。

% git clone https://github.com/laravel/homestead.git HomesteadCloning into 'Homestead'...
remote: Counting objects: 1047, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 1047 (delta 2), reused 0 (delta 0), pack-reused 1036
Receiving objects: 100% (1047/1047), 158.21 KiB | 90.00 KiB/s, done.
Resolving deltas: 100% (606/606), done.
Checking connectivity... done.


さらにHomestead.yamlを作る。

% cd Homestead/
% sh init.sh
Homestead initialized!


更にHomestead.yamlを見ると、ProviderはVirtualBoxなので問題無し。

% cd ~/.homestead/
% grep provider Homestead.yaml 
provider: virtualbox

更にSSH Keyを作る。

% ssh-keygen -t rsa -C "you@homestead
"Generating public/private rsa key pair.
Enter file in which to save the key (/Users/<username>/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/<username>/.ssh/id_rsa.
Your public key has been saved in /Users/<username>/.ssh/id_rsa.pub.
...(中略)...


SSH Keyのファイル名を変える。

% cd ~/.ssh/
% mv id_rsa Homestead
% mv id_rsa.pub Homestead.pub


Homestead.yamlに色々と設定(以下、変えた所だけ)。

% cd ~/.homestead/
% vi Homestead.yaml
(前略)
ip: "192.168.11.11"
authorize: ~/.ssh/Homestead.pub
keys:    - ~/.ssh/Homestead
(後略)

さて、ここでHomesteadを立ち上げる

% vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'laravel/homestead' is up to date...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 80 => 8000 (adapter 1)
    default: 443 => 44300 (adapter 1)
    default: 3306 => 33060 (adapter 1)
    default: 5432 => 54320 (adapter 1)
    default: 22 => 2222 (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
    default: Warning: Connection timeout. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.3.14
    default: VirtualBox Version: 5.0
==> default: Setting hostname...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/<username>/Homestead
    default: /home/vagrant/Code => /Users/<username>/<app name>
==> default: Running provisioner: file...
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: ssh-rsa XXXXX you@homestead
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: Running provisioner: shell...
    default: Running: /var/folders/x_/0yldqsjd5ln1wwkq877_yms40000gq/T/vagrant-shell20150726-25772-3a6mwz.sh
==> default: Running provisioner: shell...
    default: Running: /var/folders/x_/0yldqsjd5ln1wwkq877_yms40000gq/T/vagrant-shell20150726-25772-1qvawnk.sh
==> default: nginx stop/waiting
==> default: nginx start/running, process 1823
==> default: php5-fpm stop/waiting
==> default: php5-fpm start/running, process 1838
==> default: Running provisioner: shell...
    default: Running: /var/folders/x_/0yldqsjd5ln1wwkq877_yms40000gq/T/vagrant-shell20150726-25772-16v1opw.sh
==> default: Warning: Using a password on the command line interface can be insecure.
==> default: Running provisioner: shell...
    default: Running: /var/folders/x_/0yldqsjd5ln1wwkq877_yms40000gq/T/vagrant-shell20150726-25772-1kgrvd.sh
==> default: createdb: database creation failed: ERROR:  database "homestead" already exists
==> default: Running provisioner: shell...
    default: Running: /var/folders/x_/0yldqsjd5ln1wwkq877_yms40000gq/T/vagrant-shell20150726-25772-8nfae9.sh
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: php5-fpm stop/waiting
==> default: php5-fpm start/running, process 1928
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: Updating to version c6cc6dd6070871f4b198ed39f76dd8047c116b02.
==> default:     Downloading: Connecting...
==> default:
==> default:     Downloading: 100%
==> default:        
==> default:
==> default: Use composer self-update --rollback to return to version c43a39f7334ae3df968cd36a6eff0436bea0da75
==> default: Running provisioner: shell...
    default: Running: /var/folders/x_/0yldqsjd5ln1wwkq877_yms40000gq/T/vagrant-shell20150726-25772-5gwe60.sh


というわけで無事起動した模様。後は、/private/etc/hostsにhomestead.appを名前解決するエントリだけ追加して終了。

% cd /private/etc
% sudo vi hosts
Password: *****

エントリはこんな感じ。IPは~/.homestead/Homestead.yamlで設定したのに合わせる。

192.168.11.11   homestead.app

% ping homestead.app
PING homestead.app (192.168.11.11): 56 data bytes
64 bytes from 192.168.11.11: icmp_seq=0 ttl=64 time=0.650 ms
64 bytes from 192.168.11.11: icmp_seq=1 ttl=64 time=0.496 ms

.....

これでどうやら立ち上がった模様。