デラーズ・ブートキャンプ

プログラミングとロードバイクの事をつらつらと

2019年の抱負を考えるのに書き初めした

あけましておめでとうございます。目標をたてるのも楽しくやりたいので、書き初めイベントを開催しています。毎年数人付き合ってくれるので、楽しく目標をたてる事ができるのでおすすめです。字を書くことも少なくなってきていて、自分が字を忘れていくヤバみを確認する事もできます(汗

今回書いた内容は「出力」「東京マラソン完走」「計測」「記録」我ながら小学校低学年レベルの漢字しか出てきませんが、ネタっぽい事を含めて色々書いているうちにどんな事をしたいのかが出てきました。

出力(アウトプット)

情報収集することは好きなんですが、SNSやブログへのアウトプットを全くと行っていいほどしていないので、一貫してしたいなぁと。誰かの役に立つような事をたくさん配信できたらいいなと思っています。これに関しては計測の仕方がちょっと難しいですが、フォロワーをたくさん増やすなどで計測したいと考えています。あと、最近気がついたけど、ネットコミュ障なので、それも一緒に直したいです(笑)

計測・記録

似たような意味の事を2つ書きましたが、今まで1つはお金の出入りが結構雑に管理していましたが、これをちゃんとするようにします。もう1つはなんでも記録しておいて、考えた事や判断した事をあとから振り返りできるようにしたいです。最初に書いてたアウトプットをしっかりできていればいいんだろうと思います。

東京マラソン完走

これはそのまんま、3月3日の東京マラソンで初マラソンをするので、ちゃんと完走したいです。そのために月間150km走ってます。欲をいうとサブ4を目指したいのだけれど、今の手応えからして難しそうだ・・・。ただ、これ、3月頭で一段落してしまうので、最低もうひとつ運動系の目標を立てたいなとは思っていて、何しようかな。自転車も去年ヒルクライムもやったし、ツールド東北にも行けたので、特に参加したいイベントもないので考え中。多いな考え中・・・。

その他

毎年よりもちょっとぼんやりした内容になったと自分でも思いましたが、1年ちょっとお世話になった職場をやめて、新しい案件を探しています。まだ何も決まっていないので、内心不安だらけですが、チャレンジする年にしたいと思っています。

2019年の抱負を考えるのに書き初めした

はじめまして、あけましておめでとうございます。

目標をたてるのも楽しくやりたいので、書き初めイベントを開催しています。毎年数人付き合ってくれるので、楽しく目標をたてる事ができるのでおすすめです。字を書くことも少なくなってきていて、自分が字を忘れていくヤバみを確認する事もできます(汗

今回書いた内容は「出力」「東京マラソン完走」「計測」「記録」我ながら小学校低学年レベルの漢字しか出てきませんが、ネタっぽい事を含めて色々書いているうちにどんな事をしたいのかが出てきました。

出力(アウトプット)

情報収集することは好きなんですが、SNSやブログへのアウトプットを全くと行っていいほどしていないので、一貫してしたいなぁと。誰かの役に立つような事をたくさん配信できたらいいなと思っています。これに関しては計測の仕方がちょっと難しいですが、フォロワーをたくさん増やすなどで計測したいと考えています。あと、最近気がついたけど、ネットコミュ障なので、それも一緒に直したいです(笑)

計測・記録

似たような意味の事を2つ書きましたが、今まで1つはお金の出入りが結構雑に管理していましたが、これをちゃんとするようにします。もう1つはなんでも記録しておいて、考えた事や判断した事をあとから振り返りできるようにしたいです。最初に書いてたアウトプットをしっかりできていればいいんだろうと思います。

東京マラソン完走

これはそのまんま、3月3日の東京マラソンで初マラソンをするので、ちゃんと完走したいです。そのために月間150km走ってます。欲をいうとサブ4を目指したいのだけれど、今の手応えからして難しそうだ・・・。ただ、これ、3月頭で一段落してしまうので、最低もうひとつ運動系の目標を立てたいなとは思っていて、何しようかな。自転車も去年ヒルクライムもやったし、ツールド東北にも行けたので、特に参加したいイベントもないので考え中。多いな考え中・・・。

その他

毎年よりもちょっとぼんやりした内容になったと自分でも思いましたが、1年ちょっとお世話になった職場をやめて、新しい案件を探しています。まだ何も決まっていないので、内心不安だらけですが、チャレンジする年にしたいと思っています。

2018年の目標と振り返り

はじめに

何も決めないとすぐに怠ける性格をしているので、年始に目標立て、年末振り返るというのを毎年やってます!毎月毎年ちょっとずつでも成長して行けばいつかは大木になれる絶対。

ビジネス面

本を読む

前々から、もっと本を読む習慣をつけたいと思っていて、月2冊って目標を立てたんだけど未達でした。前半はiPhoneの自動読上を使ったりして、楽しくこなしこなしていたんですが、通勤時間のお供にVoicyがとても良くフィットしたので、その流れであまり読まなくなってしまいました。Voicyは最高のメディアだと思っています !「シリコンバレー式 自分を変える最強の食事」「WEBフロントエンドハイパーパフォーマンスチューニング」「嫌われる勇気」、「シリコンバレー式 最高の睡眠」。目標数は未達でしたが、読んだ本を振り返ると、読んで良かったと思える本ばかりで目標をたててよかったです。

稼ぎをあげる

完全未達。この目標は普段から意識もしていなく、大失敗でした。失敗の要因は色々考えられますが、月次の目標を立て、具体的に何をアクションするかを決めなかった事が一番の失敗だと思います。

アウトプットする

半分未達。「カンファレンスのお手伝いをする」、「自分のサービスを1つでもリリースする」という2つの内容を掲げていまたが、お手伝いの方だけ達成でした。 今年はカンファレンスの手伝いをやろうと思っており、PHPカンファレンスのNOCチームにどのような内容をするのかもわからない状態で、NOCに応募してお手伝いしました。NOCへの参加はいい経験になりました。NOCとは、会場参加者にWi-Fiを提供するという仕事をします。インフラをメインにしているエンジニアとCONBU(Wi-Fi提供をしている有志グループ)の方々は知識豊富で、そのような方々から知識を得ることもできましたし、優秀な学生とつながったりと、刺激を受ける事が多く参加してとても良かったです。

もう一つの、自分のサービスを作るという目標は、4月くらいまでは人を巻き込んだりして、うまく勧めれていた・・・のですが、結局途中までで、一度手を止めてしまうと、もう動かずにリリースまでは行きませんでした。できる範囲で欲しいもの。自分のモチベーションが維持できるようなもの。色々考える事はある。

プライベート面

ランニング 200km

走行距離569kmというダブルスコアで達成しましたが、ノリで応募した東京マラソンに当選し、「完走しないと落選した方に申し訳ない!」と勝手に思い、完走できるようにトレーニングを開始したので、10月、11月、12月はそれぞれ、100km、170km、180km、走ったので達成できたのは当たり前です。それを抜きで考えると、月間で20km以上走ったのが1月、4月、8月、しかなかったので、微妙な結果に終わります。東京マラソン完走目標でがんばります!!

自転車 2000km

走行距離1500kmで未達。未達だったが、東京マラソンに出場で時間の使い方を走る事に優先させたので、仕方が無いと思ってます(半分いいわけ)。自転車に関しては、ロードバイクを買ったときから出たいと思っていたツールド東北に行く事ができてよかった!一緒に参加した高橋さんありがとうございました!!あと、年末から、千葉を拠点にしているグループに参加させてもらい、いい自転車ライフを遅れたし、いい出会いもあり良かったです。

今年買って(使って)よかったもの

Voicy

voicy.jp

通勤だけでは聞く時間が足りなくなってしまったので、風呂やランニングの最中のお供になりました。支援家Kさん、あやにーさん、しんたろーたりーさん、風呂敷畳人さん、はるかなさん、澤さん、せらなつこさん、を好んで聞いてます!もともとラジオっ子だったのもありますが、人の思考や好きポイントを聞いたりする事が好きなので、とても楽しんでいます。10月にはファンフェスタにも行ったのですが、前日の夜中に「お金出してでも来たいという人に来てもらいたかったから」と参加費を0円にしたりといい意味でヤバイです。

ロボット掃除機

https://www.amazon.co.jp/dp/B01M3PV96T/ref=cm_sw_r_tw_dp_U_x_GhGkCbJ4BBHV6www.amazon.co.jp

この子が来てから、お家のホコリレベルが超絶代わりました。ぶつかりながら一定時間を働き続ける頭は良くない子ですが、これで十分です。青ランプが明るくて寝るとき気になるってマイナスポイント以外は不満がまったくありません。

GoogleHomeMini & NatureRemo

「OK Goolgle いってきます」「OK Google 暖房つけて」「OK Goole 電気つけて」「OK Google 暗くして」など、リモコンをほとんど使わなくなりました。最初に購入したのはAmazonEchoさんだったりするのですが、Googleさんの方がアバウトに頼んで、理解してくれる事が多いと感じてメインはGoogleさんに。NatureRemoは競合は使っていませんが、自宅のエアコンがテンプレートに対応している機種だったので、ほとんど設定はいらなかったし、真夏の帰宅前に自宅のエアコンをオンにしたりできて、好きポイント満載でした。

まとめ

いい出会いもあり、悪くはない年だと思いましたが、改善ポイントを上げるとキリがない。もっとうまくできた思える年でした。2018年も、たくさんの方のお世話になり、感謝の気持ちでいっぱいです。残り数時間、良いお年をお過ごしください〜。

今年最初のエントリーが振り返りエントリーになってしまった・・・・(´・ω・`)

phpstormでcakephp3のテスト実行環境を作る

cakephp3のテストをphpstormのphpunit環境の設定方法を解説します。 この画像の様なテストを走らせるツールを使いたくてやりました。

f:id:Derabon:20171229194521p:plain

phpunitをインストールする

初期状態のcakephp3にはphpunitがインストールされていないのでインストールしましょう。

composerでインストールしました。 cakephpのバージョンによってチョット変わるみたいです。 https://book.cakephp.org/3.0/ja/development/testing.html を参考

$ php composer.phar require --dev phpunit/phpunit:"^5.7|^6.0"

// CakePHP 3.4.1 より前
$ php composer.phar require --dev phpunit/phpunit:"<6.0"

PHPUnitの実行設定を作成する

menu > Run > Edit Configrations... の設定を開き、左上の + ボタンから PHPUnitの設定を作成します。 Directoryの設定はcakephpのプロジェクト内のtestsディレクトリを指定し、Test Runner options: に --bootstrap {project directory}/tests/bootstrap.php と設定してやります。

初め、--bootstrapを設定していなくて、Use of undefined constant TMP - assumed 'TMP' とか言うエラーが出ていたので悩みました。

環境変数を設定したい場合は Enviroment variables: に設定すれば読んでくれます。

f:id:Derabon:20171229194841p:plain

テストを実行する。

f:id:Derabon:20171229193552p:plain

作成した設定選択して▷押したら実行してくれます。

f:id:Derabon:20171229194202p:plain

Slim3で OAuth2サーバーを構築 (リソースサーバー編)

今回は前回作ったOAuth2サーバー(ClientCredentialsGrant)で発行されたキーを使って、認証を行って通信をするサーバーの構築を行います。前回の方法で発行されたのはJWTトークンといって、トークン内に有効期限、クライアントID、スコープを含んでいます。ですので、認証サーバーで発行された publickey を使った、リソースサーバーのみの実装になります。また、league/oauth2-serverの仕様では PSR-7 のミドルウェア で実装されているので CakePHP3 等でも実装可能なはず。

環境構築

OAuth2を入れる所までは前回と同じです。 composer create-project slim/slim-skeleton php-oauth2-server composer remove slim/php-view composer require league/oauth2-server

autoloadの設定も前回と同じでOK

"autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },

実装

これもOAuth2のホームページExampleを参考にして実装していきます。(・・・認証処理で特別実装がなければRepositoryとEntityはgithubのコードそのままでいいと思われる)。あと試していないけど、AuthCodeGrantでも同じ実装で良さそう。

<?php 

# dependencies.php
$container['oauth2'] = function ($c) {
    // Init our repositories
    $accessTokenRepository = new App\OAuth2\Repositories\AccessTokenRepository(); // instance of AccessTokenRepositoryInterface

    // 認証サーバーで発行したpublickeyを指定する。
    $publicKey = 'file:///XXXXXXXXXXX/public.key';
            
    // Setup the authorization server
    $server = new \League\OAuth2\Server\ResourceServer(
        $accessTokenRepository,
        $publicKey
    );
    return $server;
};

# middleware.php
# 追加する
$app->add(new \League\OAuth2\Server\Middleware\ResourceServerMiddleware($app->getContainer()->get('oauth2')));

テスト

今回もPostmanで確認します。PostmanはOAuth2にも対応してるので便利です。認証成功したらリクエストのAttributesに OAuth_XXXXX という項目が追加されるので、リターンしてみます。

<?php 
# routes.php
# RequestのAttrebute内に認証された情報を入っているか確認
$app->get('/', function ($request, $response, $args) {
    $this->logger->info("Slim-Skeleton '/' route");
    return $response->withJson($request->getAttributes())->withStatus(200);
});

Postmanで送信 f:id:Derabon:20170629085152p:plain

f:id:Derabon:20170629085315p:plain

まとめ

これでOAuth2サーバーの構築は完了ですが、機能面の実装はもっとちゃんと考える必要があるんじゃないかと思いました。OAuth2の勉強から始まりたてる事になったので、マサカリを投げてもらえると嬉しいです。

今回できたもの

https://github.com/dera0520/php-oauth2-resource

参考

oauth2.thephpleague.com github.com/thephpleague/oauth2-server Slim 3 Framework でMySQLとテンプレつかってみる。その2

Slim3でOAuth2サーバーを構築する (認証サーバー編)

お仕事でOAuth2のサーバーを作る事があったので備忘録です。Slim3league/oauth2-server を利用して作成しました。認証方式は ClientCredentialsGrant で作成しています。

環境構築

まずはSlim3のスケルトンでプロジェクトを作成。その後composerで必要なライブラリをポンポン入れていきます。ちなみにViewは使わないのでremoveしています。dependencies.phpPHP-Viewを設定している箇所があるのでその辺も取り除くこと。

composer create-project slim/slim-skeleton php-oauth2-server
composer remove slim/php-view
composer require league/oauth2-server

次にsrc配下をautoloadさせる設定を composer.json に追記して、composer dumpautoload を実行する。これでsrc配下が namespace 配下のクラスがnamespaceで使用できるようになります。

"autoload": {
    "psr-4": {
        "App\\": "src/"
    }
},

OAuth2ライブラリのホームページを参考にprivatekeyとpublickeyを作成します。

openssl genrsa -out private.key 1024
openssl rsa -in private.key -pubout -out public.key

データを保存するテーブルの作成。

CREATE TABLE `clients` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `client_id` varchar(255) NOT NULL DEFAULT '',
  `secret` varchar(255) NOT NULL DEFAULT '',
  `scope` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE `scopes` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `scope` varchar(255) NOT NULL DEFAULT '',
  `discription` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

実装

OAuth2プロジェクトのExamplesを参考にして実装していきます。githubのコードをそのまま使用すると、データが直書きされていたりするのでその辺りを書き換えたりとかします。

# Modelやら$this->dbとか使っていますが、この辺の説明は省略します。

# AccessTokenRepository.php
    public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null)
    {
        $accessToken = new AccessTokenEntity();
        $accessToken->setClient($clientEntity);
        foreach ($scopes as $scope) {
            $accessToken->addScope($scope);
        }
        $accessToken->setUserIdentifier($userIdentifier);
        return $accessToken;
    }

# ClientRepository.php
    public function getClientEntity($clientIdentifier, $grantType, $clientSecret = null, $mustValidateSecret = true)
    {
        # clientsからユーザが存在するか検索
        $model = new ClientModel($this->db);
        $clientArray = $model->findByClientId($clientIdentifier);
        if(empty($clientArray)){
            return;
        }

        if(password_verify($clientSecret, $clientArray['secret']) === false){
            return;
        }

        # client情報をreturn
        $client = new ClientEntity();
        $client->setIdentifier($clientIdentifier);
        $client->setScope($clientArray['scope']);

        return $client;
    }

# ScopeRepository.php
    public function getScopeEntityByIdentifier($scopeIdentifier)
    {
        $model = new ScopeModel($this->db);
        $scopeArray = $model->findByScope($scopeIdentifier);
        if(empty($scopeArray)){
            return;
        }
        
        $scope = new ScopeEntity();
        $scope->setIdentifier($scopeIdentifier);
        return $scope;
    }

    public function finalizeScopes(
        array $scopes,
        $grantType,
        ClientEntityInterface $clientEntity,
        $userIdentifier = null
    ) {
        // scopeが未指定の場合は client の scope をすべて設定
        // scopeが指定されている場合は client の scope に含まれている引数の socpe を追加して返却
        $clientScopes = $clientEntity->getScopes();
        $ret = [];
        if(count($scopes) === 0) {
            foreach($clientScopes as $s){
                $scope = new ScopeEntity();
                $scope->setIdentifier($s);
                $ret[] = $scope;
            }
        } else {
            foreach($scopes as $s){
                $paramScope = $s->getIdentifier();
                if(!in_array($s->getIdentifier(), $clientScopes)){
                    throw OAuthServerException::invalidScope($paramScope);
                }
                $scope = new ScopeEntity(); 
                $scope->setIdentifier($paramScope);
                $ret[] = $scope;
            }
        }
        return $ret;
    }

テスト

Postmanとかでテスト送信をしてみてトークンが返って来ればOKです。 f:id:Derabon:20170627125832p:plain

今回できたもの

https://github.com/dera0520/php-oauth2-server

参考

oauth2.thephpleague.com
github.com/thephpleague/oauth2-server
Slim 3 Framework でMySQLとテンプレつかってみる。その2

Phinx入門

PHPの現場でマイグレーションツールのPhinxを使い始めたのでメモ書きです。少しずつ導入し始めていますが、だいぶ具合が良いです。マイグレーションツールのノウハウなんて暫く前からあるので今更感がありますが、そこは置いておきましょう。

参考ページ

導入

今回は Phinx を個別でインストールします。Composerを使っているのであれば一撃でインストールは完了です。そうでない場合もダウンロードしてきて参照設定すればOKです。CakePHP3ではフレームワーク内に実装されているので cake.php から使う事ができるはず。

# Comporserでインストールする場合
php composer.phar require robmorgan/phinx
php composer.phar install --no-dev

# コマンドの実行でバージョンが表示されればOK
vendor/bin/phinx -V
Phinx by Rob Morgan - https://phinx.org. 0.8.1

phinx.yml が設定ファイルです。 migrationを保存するディレクトseedを保存するディレクトDBの接続設定 を行います。また、ここで指定したディレクトリも忘れずに作成しましょう。

マイグレーションファイルの作成

# createコマンドで雛形生成
vendor/bin/phinx create NewHogeMigration  # マイグレーション名はキャメルケース

# migrationディレクリにファイルが作成されました
ls db/migration
20170618080652_new_hoge_migration.php
# 20170618080652_new_hoge_migration.php
# コマンドで作成した場合 change() メソッドが初期で作成されていますが、
# クエリの実行のみで入門した方が分かりやすいため下の内容に書き換え

<?php 
use Phinx\Migration\AbstractMigration;
class NewHogeMigration extends AbstractMigration
{
    /**
     *  create hoges talbe
     */
    public function up(){
        $count = $this->execute('
            CREATE TABLE `hoges` (
              `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
              `name` varchar(100) DEFAULT NULL,
              `email` varchar(255) DEFAULT NULL,
              PRIMARY KEY (`id`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
        ');
    }

    /**
     * drop hoges table
     */
    public function down(){
        $count = $this->execute('DROP TABLE hoges;');
    }
}

実行

migrate
# upメソッドが実行され `hoges` テーブルが作成されます。
# また、migrationの情報もDBに保持するため、`migrations` テーブルが作成されデータが更新されます。
vendor/bin/phinx migrate
rollback
# downメソッドが実行され `hoges` テーブルが削除されます。
vendor/bin/phinx migrate

初期データの作成

vendor/bin/phinx seed:create HogeSeeder
# HogeSeeder.php
<?php 
use Phinx\Seed\AbstractSeed;
class UserSeeder extends AbstractSeed
{
    public function run()
    {
        $faker = Faker\Factory::create('ja_JP');
        $data = [];

        ## 100件のダミーデータを作成
        for ($i = 0; $i < 100; $i++) {
            $data[] = [
                'name' => $faker->name,
                'kana' =>  $faker->kanaName($gender = null|'male'|'female'),
                'email' => $faker->email,
                'created' => date('Y-m-d H:i:s'),
            ];
        }
        $this->insert('users', $data);
    }
}
Faker

ダミーデータの作成には Fakerを使います。未インストールの場合は composer require fzaninotto/faker でインストールします。

Seedの実行
# -sオプションでSeedファイルを指定
vendor/bin/phinx seed:run -s HogeSeeder