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

ギークになりたいプログラマの日記

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

go言語を書き始めました

最近go言語を書きはじめました。その備忘録としてブログ書いておこうと思って久しぶりの投稿です。

環境

go言語は homebrew でインストールして、GOPATH 等は設定済みを想定しています。

IntelliJ IDEA の設定

“go"でプラグインを検索すると2つ開発環境のプラグインが出てくるんだけど、"Go language” ではなく “Go” の方をインストールする。前者の方はスター数は多いけど、開発が止まっているみたいで1.8に対応して無いみたいだった。(最初にインストールしてインテリセンスがおかしくてハマった)

f:id:Derabon:20170530084717p:plain

次にIDEからのユニットテスト環境変数を読み込ませる設定。メニューから RunEdit Configurerations... で設定画面を立ち上げて、DefaultsGo Test を設定すれば、テスト時に環境変数を読み込む事ができる。ちなみにこの技は先日もくもく会に参加した時に教えてもらいました!

f:id:Derabon:20170530124322p:plain

なんだかIntelliJの使い方みたいな記事(しかも薄い)になってしまったけど今回はこの辺で

gem install mysql2 でコケたお話

MySQLのインストールがうまく行かない

環境
Ruby 2.0.0p247
Rails 4.0.2


sudo gem insatll mysql2 を実行すると

Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
	ERROR: Failed to build gem native extension.

...以下省略

こんな感じでインストールできませんでした。
実装の方法がかわったのかな???

このページを参考にして、HomebrewでMysqlをインストールしてみたらうまく行きました。
Mac OS X Lion 10.7.5 で MySQLをアップデートした後に`gem install mysql2`が失敗してしまう場合の対処法 | Ruby on Rails 備忘録 - Ride On Rails

brew install mysql
...
...
gem install mysql2
...
...

今、この本でRails&iPhoneアプリをごにゃごにゃしております。
この本、結構は書って書いてあって、ある意味勉強になる笑
Amazon.co.jp: RailsとiPhoneではじめるアプリケーション開発: 栗田 由菜, 丸山 弘詩: 本

でも結局、なじみがあるPostgreSQLに置き換えてやってみる事にしました。ちゃんちゃん


RailsとiPhoneではじめるアプリケーション開発

RailsとiPhoneではじめるアプリケーション開発

iPodでレジスター

ちょっと前の事なんだけど、外食したときに注文を"iPod touch"で注文をとって、レジはiPadでやってるお店に入りました。

物珍しかったので、フロアのお兄さんに「ハイテクですねー」と言ってみたところ、「この方が安いらしいです。」と返されました。
iPadのレジも、iPadからボタン押したら、「チャリーン♪」って音がしてレジが空いていたのがなんかよかったです。


過去にハンディーターミナルをメインで取り扱ってた経緯もあって、確かに業務用のハンディターミナルって、アホみたいに高いよなぁとか思ってました。(その分タフだったりもするけど)

この業界も黒船に侵略されてますなぁ。と思った1件でした。
これから、こういう形態のサービスもどんどん増えていきそうな雰囲気ですね。

ユビレジ - Google 検索


iPhone、iPad POSレジ スマレジ


みてた感じ、僕が立ち寄ったお店はユビレジっぽかったです。

お仕事でIISをいじったお話

お仕事でウェブサービスたてたので備忘録として書いときます。

 

目次

コケた事1 SQLServerとの接続

コケた事2 接続ユーザ設定

 

環境

WindowsServer 2008R2

IIS7

SQLServer 2008R2

VisualStudio2008

簡易WebService(C#)

 

 

作業前の状態

ローカル開発環境で機能テストを一通り終えた状態

 

コケた事1

ConnectionStringをWebConfigに書いているですが、記述の仕方をいっつも忘れる。

コンフィグの書き方

<connectionString>
<add connectionString="Server=localhost;Database=hogebase;User ID=hogeuser;Password=hogehoge" name="hogehoge_connectionstring" />
</connectionString>

コンフィグの使い方

public static GetCon(){
  return ConfigurationManager.ConnectionString["hogehoge_connectionstring"];
}

他の書き方でも動くんだろうけど、ひとまずコレで問題なく動いてます。

 

 

 

コケた事2

サービス接続用のユーザを用意して、基本認証で接続させた方法

 

まずは、マイコン右クリ→管理→ユーザーとグループを開いて、ユーザーに moge というユーザーを追加。ユーザーの所属しているグループに IIS_IUSRS を追加(最後にコレをやりました)。サービスを実態の場所のセキュリティに追加したユーザ(moge)をフルコントロールで追加

 

コレで期待通りに動かす事ができました。

 

勉強してれば、VisualStudioにツールぶっ込んで、「デプロイ、えいやっ!」ってやっると本番環境できあがり。っていう事できるのかなぁと思います。勉強不足を痛感します。