スタートアップにとって、コインチェック騒動は他人事ではない
エンジニアやスタートアップの界隈の人は既にご存知だと思いますが、コインチェック社の580億円消失騒動がありましたね。
最近のテック・スタートアップ界隈においても、最大級のネガティブインパクトのある事件だと思います。
これに対して、インターネット上では様々な意見が交わされていて、「若者の作った大学生ノリの会社なんか信用してはいけなかった」とか「仮想通貨の危うさが露呈した」とか「セキュリティが最大の強固さでなかったのが原因だろう(意訳」といった意見があるみたいです。
一方で、こういった見方は感情的には理解できるものの、問題の本質ではないように思いました。
少なくとも、新しいサービス・価値を享受する側ではなく、新しいサービス・価値をつくる側、つまりスタートアップで働く側の人間はもう少しこの問題を深く掘り下げて本質的に理解しておく必要があるなと思ったので、自分なりの理解を書き残しておきたいと思います。
問題をどう理解したか
この騒動で最も重要だと感じたのは、特定の会社や技術・市場によらず、未成熟な状態から一気に急成長する技術・市場は同じような状況に陥る可能性がいつでもあるだろう、ということです。
こう考えるポイントは、技術・市場が成熟していく過程と、ソーシャル時代の情報流通スピードにあります。
技術・市場が成熟していく過程
まず、今回のような問題が起きた要因のひとつとして、仮想通貨を取り巻く技術・市場が(特に国内において)未成熟である、という点は無視できないと思います。
数年前の話にはなりますが、マウントゴックスの消失事件などもありましたし、
コインチェックの件についても、ホットウォレットで管理されていた点やマルチシグが実装されていなかった点を「セキュリティの甘さ」として追求されていることや、仮想通貨交換業者登録の認可が下りていなかったことからも分かる通り、この市場には完全なセキュリティを備えたプレイヤーでなくても参入できるという現状があります。 そもそもとして、この分野における完全なセキュリティというものがなにか、まだ誰もわからない状態にあるのかもしれません。(このあたりは詳しくないので多分に想像にすぎませんが)
こういった仮想通貨技術・市場を取り巻く状況に対して、「事業者なのだから、未成熟であったという言い訳はきかないだろう」という指摘はごもっともと思いますが、現実として未成熟である、という点は否めないと思います。
そして、技術・市場が成熟するためには、必ず辿らざるを得ない、回避できないプロセスがあると思います。
それは、失敗を繰り返し強固なシステムをつくりあげる、というプロセスです。
この前提にあるのは、(個人としても、組織としても、市場としても)事前に全てのリスクを想定し全てのリスクを回避することは不可能である、という事実です。
よく仮想通貨の安全性と比較して銀行や証券といったシステムが挙がりますが、銀行や証券といったシステムも、それが登場したばかりのころは色々な問題を抱えていたであろうことは間違いないと思います。失敗を繰り返し、長い時間をかけてひとつひとつ問題解決をしてきた結果、今のような強固なシステムをつくりあげたのだと思います。
そして、仮想通貨やその周辺の技術・市場に関しては、今はまだ強固なシステムをつくりあげていく途中のフェーズにあります。
そういったフェーズであるにも関わらず、大きくマスに普及し、大きなリスクが表出しやすい状態に至ってしまったことが、今回の騒動が大きくなってしまった原因だと思います。
ソーシャル時代の情報流通スピード
現代は昔に比べて、リスクの大規模表出が起きやすい状態にあると思います。そう思う主因は、情報流通スピードの違いです。
銀行や証券のシステムができた当時と、仮想通貨が登場した現代は、情報流通のスピードが桁違いです。 技術・市場が成熟していくために必要な小さい失敗を積み重ね、強固なシステムをつくりあげるよりも前に、SNS等の拡散力によって物凄い勢いでマスに広がってしまいやすい状況にあります。 (今回の件に関しては、まだリスクに見合うだけの成熟したシステムが出来上がっていないにも関わらず、マスメディア(CM)による更なる成長の加速を図ったという点は、コインチェック社の犯した大きなミスのひとつかなと思いました。)
つまり、技術・市場の(規模)成長スピードが技術・市場の成熟スピードを追い越してしまいやすいのです。
一般的に、利用者が多くなればなるほど、市場が大きくなればなるほどリスクは表出しやすく、大規模化しやすくなりますから、まだ未成熟で強固なシステムが出来上がっていないサービスがマスに広がってしまえば、大きな問題が起きやすくなるのは必然です。
スタートアップが肝に銘じておくべきことはなにか
上述してきた通り、技術・市場の流通規模に対して技術・市場の成熟度のバランスがうまくとれなければ、仮想通貨に限らず、どんな技術・市場も今回のような問題を引き起こしてしまう可能性を孕んでいると言えると思います。
スタートアップ界隈では「勢い良く成長していること」がもてはやされますし、実際のところ急速に成長しないスタートアップには存在意義がない(というよりスタートアップとは言わない)とも思いますが、成長に見合うだけの成熟度(システムの強固さ)を獲得できているか、はあまり話題にのぼらないように思います。
ここを気にしすぎては新しい発想・新しい事業・新しいチャレンジが生まれにくくなるだろうという思いもありつつ、ここを無視しすぎては今回のような大きな問題を起こしてしまう可能性が高まるのは避けられないだろうとも思います。
いわゆるスタートアップに所属し、未成熟な市場での急成長を目指すプレイヤーの立場として、時には多少の成長スピードを諦めてでも成熟を待ったり、成長スピードに追いつくために成熟度を上げる部分に投資したりといった視点でのマネジメントも必要なのだろうな、と今回の騒動を通して感じました。
自分たちの提供しているサービスはどの程度の成熟度にあるのかをきちんと踏まえながら、闇雲に多くの人に利用していただくのではなく、成熟度に見合った適切な人に利用していただくという運営をしていかなければな、と思います。
最後に
まだどうなるか確定的ではなさそうな感じですが、今回の騒動で資産を失ってしまったみなさん、ご愁傷様です。
(追記)戻ってくるみたいですね!おめでとうございます!
スタートアップのエンジニアになってました
以前に下記の記事でWebエンジニアになったことは書いていたのですが、
この時の転職先の会社に2年お世話になったあと、今年の5月にまた転職しまして、今は都内のスタートアップでエンジニア・プロダクトマネージャーとして働いています。
なぜスタートアップに転職したのか
前回は2015年5月に転職したのですが、Webエンジニアへのキャリアチェンジだったこともあり右も左もわからず直感で選んだにも関わらず、運良くかなり素晴らしい会社に転職できました。
この会社では、エンジニアがビジネス・事業の側面に積極的に絡んでいく文化的素地があったこともあり(またその点がこの会社の強いところでした)、エンジニアリングに関することはもちろん、Webのビジネスやスタートアップの文脈についてもかなりの部分を学ぶことができました。
小さいエンジニアチームのリーダーを任せていただいたり、プロダクトマネジメントをやらせていただいたり、R&D的な開発も経験させてもらいました。
そうした恵まれた環境で1年半ほど学ばせてもらうなかで、Webエンジニアリングについてもビジネスについても基礎の部分はかなり身についたなという実感がありました。次は応用・実践に比重を置く必要があるなと。
そう考えた時に、もともとどちらかというとエンジニアリングのプロフェッショナルというよりは、サービスをつくることやビジネス・事業開発に興味があるタイプだったこともあって、自分でWebサービスの事業を作ってみたいと思うようになりました。
ここで言う「自分でWebサービスの事業を作る」というのは、平たくいうと自分のあらゆる意思決定がプロダクト・事業の方向性に大きく寄与する環境に身を置きたいということでした。
また、自分が今年30歳を迎えるということで、なにか大きなチャレンジをするなら節目のタイミングだなと思ったことも小さな理由のひとつです。
今、なにやってるのか
いわゆるシェアリングエコノミーの文脈のサービスを開発しています。 会社としては2人目のエンジニアとして参加しました。
立場的には、プロダクトマネージャーとエンジニアを兼務している形ですが、まだ全社で10人ちょっとの会社なので役割はあってないようなもので、自分の持ってるスキルを活かしてバリューが出せそうなことは何でもやる、という感じです。
例えばこんな感じのことをやってます。
- プロダクト開発
- 企画〜実装〜リリース
- バックエンド
- フロントエンド
- インフラ
- DevOps
- その他必要なことなんでも
- プロダクトチームづくり
- エンジニア採用
- デザイナー採用
- 学習するチームの仕組みづくり
- 開発指針の策定
- データ分析基盤(BIツール)の導入
- プロダクトマネジメント(プロダクト・マーケ戦略、KPI設計など)
入社してすぐのころに1人目のエンジニアの方がフルタイムでなくなったこともあり、リソースに課題が出てきそうなのが見えたので、採用をやらせてもらいました。これが入社して最初の仕事と言ってもいいかもしれません。 (前職が人材分野だったので、そこで学んだことがかなり役立ちました)
結果、2名のエンジニアの仲間に入社してもらうことができ、今は徐々にチーム開発になりつつあり、開発のスピードが上がってきそうだなというのが見えてきたところです。
プロダクトに関してはほぼ全面的に裁量があるような形で、かなり幅広く色々なことをやらせてもらえており、自分の志向性にとても合っているので楽しく働いています。
これまでの経験を活かせるシーンも多くありつつ、新しい学びを得られることも多いので、自分的にはかなり理想的な状況です。
直近は、この会社で事業を大きく成長させるのが自分の仕事になります。
ということで
せっかくスタートアップという変化の大きい環境にきたので、色々書けることも増えそうだし、暇をみつけてブログを書いていこうかなと思います。
組み込みエンジニアから、Webアプリエンジニアに転身しました。
突然ですが、転職いたしまして、この5月からWebアプリエンジニアになりました。
転職をしようと決めたのは2月の末ごろでした。 決めてからはトントン拍子に進んで、2週間ぐらいで転職先が決まりまして、この5月から入社した形です。
もともと、「組み込みエンジニアが週末を使ってWebアプリエンジニアになるブログ」と謳って始めた本ブログでしたが、週末だけに留まらず、本職を変えてしまうことになりました。
今後、この決断がどういった結果をもたらすのかはわかりませんが、今の時点の気持ち、転職を決めるにあたって考えたことを記しておきたいと思います。
もっとWebアプリに触れる時間が欲しかった
前職はそこそこに忙しく、Webアプリのために多くの時間を割くのは難しい状況にありました。 帰宅後の夜や週末の限られた時間を使って取り組んでいたものの、目指すスピード感にはほど遠いなと感じていました。
Webアプリの勉強を始めてからは、久しぶりに技術的に新たな刺激となっており、とても楽しく充実感があったので、そのために時間を割くことができない日々は、正直言ってかなりもどかしかったです。
そのため、もっとWebアプリに日常的に触れていられる環境に身を置きたいという思いが強くなりました。
もっと成長できる環境に身を置きたかった
前職は規模の大きい企業だったことや、歴史の長い企業だったこともあり、いわゆる「上が詰まっている」状態がかなり顕著でした。
また、完全な年功序列制であり、年齢が上がらなければ待遇は上がらず、同時にできる仕事のレベルも上がらない仕組みでした。
そのため、今やっている仕事のレベルから一段上の仕事をやれるのは、おそらく数年後になってしまう見込みでした。
会社としてソフト開発への理解や投資も乏しく、手を挙げても挑戦することもなかなかできない状態にありました。
そういった状況を鑑みて「20代後半の、一番成長できる時期に、本当にここにいていいのか?自分の成長に蓋をしてしまっているのではないか?」ということについては、ずっと懸念に思っていました。
組み込みという閉鎖的な分野であり、その中でも職人的要素の薄いアプリケーション層を担当していたこともあって、このままでは企業ロックインしてしまい、ソフトエンジニアとして世の中で通用しなくなってしまうのではないか?という危機感もありました。
このようなことから、決して前職の企業体質を批判するわけではないのですが、私にはもっと違う環境が合っているのではないか、という思いが常にありました。
もっと本質的に価値のあることをやりたかった
前職は元々は事業会社ですが、最近ではOEM比率がかなり上がっていました。
OEMの事業はクライアント(発注元の企業様)の求める製品を作りますので、当然、クライアントの意向を汲みながら開発していくことになります。
この時、両者で本当に価値のあるものを追求していければよいのですが、クライアント側のソフトウェアに関する理解が乏しい場合や、企業としての力関係に大きな差がある場合、そうはならないことが多いです。
ある種、パワーゲーム的な面が存在してしまいますので、クライアントの議論・説得を試みることすらできないまま「会社としては価値がないと判断していても、クライアントの要望があるから開発する」といったケースや、「意味がないけど、クライアントが要望しているから資料を作成する」といったようなことも、日常茶飯事です。 酷い場合には、これらの作業が全工数の3割〜半分程度を占めてしまうこともあります。
プロダクトやサービスの本質的な価値にコミットしない仕事に、それだけの工数をかけているわけです。そして、そこでかけた工数は、もちろんユーザーが購入するプロダクトの価格にもダイレクトに影響します。
企業同士のビジネス上のやりとりとしては、これらが重要な意味を持っているであろうことは重々理解しています。
しかし、本来は「無くなるべきもの・こと」であることは間違いないと思います。
企業同士の関係性やビジネス上の駆け引きといった余分なことが、プロダクトやサービスの本質的な価値を損なっている状態に思えました。
そして、そういう仕事をしている自分が非常に虚しく思え、モチベーションがなく、疲れてしまっている状態でした。
そのため、転職にあたっては「なにをやるかを全て自分たちで決めて、その結果の責任が全て自分たちに返ってくる」という性質の仕事をしたいと思いました。
その答えが「自分たちのプロダクトやサービスを直にエンドユーザーに届ける、事業会社」という選択でした。
そして転職へ・・・
そんなわけで、主に人材採用の領域でWebサービスやスマートフォンアプリの展開をしているベンチャー企業に、Webアプリエンジニアとして入社しました。 今はバックエンド周りの開発を担当しています。
転職先を決めるにあって、重視していたのは下記の様な点です。
- 優秀なエンジニアが多数在籍している(成長を加速できる要因として)
- 受託をやっていない事業会社である(会社として腹落ちした価値のあることに取り組める)
- 挑戦を尊ぶ風土がある(成長を加速できる要因として)
- ソフト開発に対する投資に積極的である(環境の制限がボトルネックになり辛いこと)
- ビジョンに共感できる(ここがズレると、色々なところで違和感を感じてしまうので)
私はWebアプリ開発については業務での経験は全くなく、前職ではほとんどコードを書いておらずマネジメントがメインでしたので、ポテンシャル採用のような形だったかと思います。
入社して一ヶ月経ちましたが、今のところはおおよそ想像していた通りの環境で、非常に刺激的です。
急拡大中の企業なので、課題も多く、課題を解決するのにマッチした人材が足りていない印象もあり、私のこれまでの経験を活かせる領域も大分ありそうな気がします。
現時点での私の強みは、マネジメントや要件定義(広義の企画)といった部分だと思いますが、これを活かすための地盤を作る意味でも、まずはWebアプリエンジニアとしての基礎力を鍛えることと、自社サービスの全体像を理解することに注力したいと思います。
目指す方向性としては、技術にトコトン注力するというよりは、よりよい開発ができる文化作りや、ビジネスをエンジニアリングの視点からドライブするというようなところにコミットできるようになっていければと思っています。(現時点の考えなので、半年後、一年後にどういう考えになっているか楽しみです)
ひよっことはいえWebアプリエンジニアになったので、大手を振ってそっち方面の勉強会に出かけられる(!)ということで、今後はそっち方面のイベントに顔を出したりすることも増えるだろうと思いますので、諸先輩方につきましては仲良くしていただけましたら幸いです。
よろしくお願いします!
Eloquentを使いこなせないと思ったらTwigが使いこなせてなかった話
こんばんは。
昨日、こんな記事を書きました。
LaravelのEloquentを使いこなせない話 - ミリサイズ
「Eloquentを使いこなせない話」と書いてましたが、実はTwigを使いこなせてなかった話だったので、お詫び訂正と"こうやったら解決しました!"ということを書いておこうと思います。
ごく初歩的なミスだったのでお恥ずかしく地面に埋まりたい限りです。
Twigの配列(またはコレクションオブジェクト)の扱い方
Eloquentから取得したデータは前回と同じです。 もう一度載せると、下記のような感じです。 (厳密には、arrayではなくコレクションオブジェクトですが、Twig上での扱いは変わらないようなのでこんな構造だよということで簡易的に書いてます)
array[0]{ ["id"] => 123456 ["screen_name"] => "8みり" ["screen_id"] => "8miri" ["prof_image_url"] => "http:xxx.png" ["sheets"] => array[0]{ ["id"] => 1 ["event_id"] => 1 ["user_id"] => 123456 ["type"] => "アリーナ" } }
これをTwigにusersという名前で渡して、sheetsの中身を表示しようとした場合、
{% for user in users %} UserID:{{user.id}}<br>ScreenID:{{user.screen_id}}<BR>Type:{{user.sheets.type}} {% endfor %}
だとうまくいかない!という状況でした。
昨日は行き詰まり感もあり諦めたのですが、今日になり、リフレッシュした頭でよくよく考えてみると、ん?これでうまくいかないのは当たり前な気がしてきたぞ、と。
で、書きなおしたのがこれです。
{% for user in users %} {% for sheet in user.sheets %} UserID:{{user.id}}<br>ScreenID:{{user.screen_id}}<br>Type:{{sheet.type}}<br> {% endfor %} {% endfor %}
で、表示させてみると、、、
UserID:123456 ScreenID:8miri Type:アリーナ
キタ!
あっさりできちゃいました。
見落としていたのは、Twigのforを使った配列アクセスがどうなっているのかという点でした。
Twigの処理はこうなっていた
Twigに渡したコレクションオブジェクトがどうなっていたか?を思い出してみましょう。
array[0]{ ["id"] => 123456 ["screen_name"] => "8みり" ["screen_id"] => "8miri" ["prof_image_url"] => "http:xxx.png" ["sheets"] => array[0]{ ["id"] => 1 ["event_id"] => 1 ["user_id"] => 123456 ["type"] => "アリーナ" } }
こうなっていますね。
そして、Twigにはusersという名前で渡しているので、例えば"screen_name"を取り出すには、users.0.screen_name
でアクセスする必要があります。
ん?でもそういう書き方してないよな?
・・・アッー!
{% for user in users %} UserID:{{user.id}}<br>ScreenID:{{user.screen_id}}<BR>Type:{{user.sheets.type}} {% endfor %}
そう、forを使っていたのでした。
Twigのfor文は、例えば上の書き方だと"usersの[n]番目の要素(users.n)を先頭から最終まで一個ずつ取り出して、userに突っ込んで、繰り返し中身を処理するよ"ということです。foreachと同じです。
なので、forの中で使っている"user"には一回目は"users.0"が渡されているわけです。 (わかると思いますが、二回目は"users.1"が渡されます。要素があれば。)
つまり、このforの中で1回目の'user.sheets.type'は'users.0.sheets.type'という呼び出しをしていることと同義になります。
ここで、Twigに渡したコレクションオブジェクトの構成(sheetsの中だけ)をもう一度振り返ってみましょう。
["sheets"] => array[0]{ ["id"] => 1 ["event_id"] => 1 ["user_id"] => 123456 ["type"] => "アリーナ" }
うん、sheets.0.type
ってやらないとダメじゃん、これ。
で、一人のユーザーに対してsheetsが複数とれた場合はこうするよな、ということで書き換えたのがさっきのこれです。
{% for user in users %} {% for sheet in user.sheets %} UserID:{{user.id}}<br>ScreenID:{{user.screen_id}}<br>Type:{{sheet.type}}<br> {% endfor %} {% endfor %}
入れ子になっている{% for sheet in user.sheets %}
で、sheetにuser.sheets.nを毎回渡しているので、sheet.type
はuser.sheets.n.type
と同義なので、うまく取得できます、ということになります。
なぜこんなことに気付かなかったのだろう・・・という感じですが、とりあえず思い通りの出力ができるようになったので良かったです!
TwigとEloquentにごめんなさいm( )m
LaravelのEloquentを使いこなせない話
Laravelのデータベース操作を学ぼうということで、Eloquent周りを色々触ってみていました。
PM17:00ごろ、「今日は時間もあるし、触り倒すぞー!」とノリノリでSublimeTextを開く私に、まさかこんな悲劇が待っていようとは、この時は思いもしないのでした……。
なお、本記事ではこんなテーブル構成を想定しています。
(実際はeventsテーブルというものもあります。カラムもだいぶ省いてます)
- usersテーブル
カラム | 型 | 詳 細 |
---|---|---|
id | INT | 主キー。 |
screen_name | VARCHAR | Twitterで設定している名前。 |
screen_id | VARCHAR | TwitterID。 |
prof_image_url | VARCHAR | TwitterアイコンのURL。 |
- sheetsテーブル
絡む | 型 | 詳 細 |
---|---|---|
id | INT | 主キー。 |
event_id | INT | 公演情報ID。外部キー。 |
user_id | INT | usersテーブルとの外部キー。 |
type | VARCHAR | 席種。 |
Eloquentで簡単データ取得
まずは、単純に1つのテーブルからデータを取ってくることをやってみました。
$user = User::find(1);
なんと、これだけでUserModelに紐付いたテーブル(デフォルトだとusersテーブル)から、主キーで1レコード取得できてしまいます。超簡単!
Eloquentで関連テーブルから簡単データ取得
では、usersテーブルと紐付いたsheetsテーブルからレコードをとってこようということで、やってみました。
<?php use Illuminate\Auth\UserTrait; use Illuminate\Auth\UserInterface; class User extends Eloquent implements UserInterface { use UserTrait; // 〜中略〜 /** * get the sheating information related to the user. * * @return void */ public function sheets() { return $this->hasMany('Sheet'); } }
public function sheets()
以下の定義をすると、「UserモデルはSheetモデルと一対多の関係ですよ」という意味付けになり、Userモデル経由でSheetモデルの値をとってこれるようになります。
実際に取得する部分は、こんな感じに。
$user = User::find(1)->sheets;
こうすると、Userモデルの主キー1に紐づく、Sheetモデルのレコードをとってこれます。
こんな感じでデータが扱えます。
echo $user[0]["event_id"]; // 1レコード目のevent_idの値が出力されます echo $user[0]["user_id]; // 1レコード目のuser_idの値が出力されます echo $user[0]["type"]; // 1レコード目の(ry
これも感動するぐらい超簡単ですね!
Eloquentで複数テーブルの結合結果を取得
ここまで順調にきてほくほく状態なわけですが、次に「あるID(users)を指定して、usersテーブルとsheetsテーブルからそのIDに該当するデータを全てとってこよう!」と思い、やってみることにしました。
書き方はこんな感じです。
$user = User::find($user_id)->with('sheets')->get();
で、sheetsテーブルの値を出力してみるぞとおもむろにキーボードに手を置く私。
「・・・どうやるんだ?」
sheetsテーブルの値って、どんな風にとれてるんでしょうか。
echo $user[0]["type];
とかやったら出るのかな?
よし、やってみよう。
・・・あえなくエラーで撃沈。
じゃあ、どういう風に値がとれているのか見てみよう!
ということで、中身を見てみました。
すると、こんな風にとれているようでした。 (型とか省いてて若干正確さにかけますが、こんなもんだということで)
array[0]{ ["id"] => 123456 ["screen_name"] => "8みり" ["screen_id"] => "8miri" ["prof_image_url"] => "http:xxx.png" ["sheets"] => array[0]{ ["id"] => 1 ["event_id"] => 1 ["user_id"] => 123456 ["type"] => "アリーナ" } }
なるほど…sheetsテーブルの情報は入れ子の中にくるわけだ。
ふむふむ。データ構造はわかった。
じゃあ、次はこれをTwigで出力してみよう!
{% autoescape true %} <html> <head> <meta charset="UTF-8"> <title>TwigTest</title> </head> <body> TwigTest<br> {% for user in users %} UserID:{{user.id}}<br>ScreenID:{{user.screen_id}}<BR>Type:{{user.sheets.type}} {% endfor %} </body> </html> {% endautoescape %}
出力結果:
UserID:1
ScreenID:8miri_dev
Type:
・・・あれ?typeが出てないな?
なんでだろう。
ここから、長い旅が始まりました。
Twigで入れ子arrayを取得できるのか調べてみたり、記法を[ ]使う方で試してみたり、色々やってみるものの一向に解決策が見つからず。
うーん困った!
結論
Eloquentの取得結果を、Twigでうまく扱えるデータ構造に入れなおしてやればいいのでしょうけど、それやるんならもうEloquent使わないほうがいいよね!!!!(泣)
ということで、明日からクエリービルダーで出直します。トホホ。
Twigでうまく扱えるよ?という情報をお持ちの方がいたら、お待ちしてます。(切実)
2015-01-31 自己解決しました!勉強不足でした!
LaravelでTwitter OAuth認証してみた
だいぶ前ですが、LaravelでTwitter OAuth認証を実装してみました。
いくつか詰まったことがあったので、書き残しておこうと思います。
今回、LaravelのUser認証の仕組みと、TwitterOAuth認証パッケージを組み合わせて作っています。
ちなみに、この記事は詰まったことだけ書いてあるので実装の中身は書いてません。
実装の中身については、すでに参考になる記事を書かれている方がいるので、そちらを見たらあまり悩むことなくできるかと思います。
要するに丸投げです!
下記の記事など参考にさせていただきました!
blog.ISHINAO.net | Laravel 4でTwitterログイン機能を作ってみる
laravel-twitterの導入
TwitterOAuth認証の部分は、TwitterOAuth Service Provider for Laravel 4というパッケージを使っています。
OAuth認証以外のTwitterAPIの利用も、これを導入すればいけます。
導入に関して一点詰まったところ。注意。
Githubを見ると、composer.jsonに下記のように追記するように書かれています。
{ "require": { "laravel/framework": "4.0.*", "philo/laravel-twitter": "dev-master" }, "minimum-stability": "dev" }
しかし、このように記載すると、今回導入したいlaravel-twitter以外のものについても、開発版(dev)になってしまいます。
minimum-stabillityがdevになっているせいです。
基本的には安定版を使いたいですし、なんかイマイチなので、下記のように書き換えて導入しました。
{ "require": { "laravel/framework": "4.2.*", // Versionはそれぞれの環境による。 "tijsverkoyen/twitteroauth": "@dev", // laravel-twitterがtwitteroauthを利用するので、これも指定しないと怒られた。 "philo/laravel-twitter": "@dev" // @dev指定することで、開発版になる。 }, "minimum-stability": "stable" // ここはstableなので、@dev指定したパッケージ以外は全てstable(安定版)になる }
これで、composer update。
無事開発版にしたいところだけを開発版にすることができました。
composerってむずかしいね!
導入自体は他のパッケージと同じように。
GithubのREADME見ればすぐわかる。簡単!
Usersテーブルの作成
テーブル作成時の注意点。
デフォルトでは、'id'カラムが必須になっているようです。
これを作らないと怒られます。
ちなみに、主キーも'id'がデフォルトのようなので、'id'キーをどうしても作りたくない場合をのぞいて、'id'カラムは素直に用意したほうが楽ちんかもしれないですね。
TwitterからのCallBackを受ける
Twitter認証が必要なアプリを使ったことのある人はわかると思うのですが、認証の際に一旦Twitterの認証画面に遷移して、認証完了後に元のサイトに戻ってくるという流れになります。
この戻ってくるアドレスは、TwitterAppsのページで設定します。(Callback URLという設定項目があります)
が、localhostへCallBackさせることができません!
http://localhost:8000/のように書くと、その設定はできないぜと怒られます。
ビルトインサーバーで開発していると、localhostが標準なので、そのままではCallBackを受けれないことになります。
一瞬「こりゃ困ったぞ!!」と思いましたが、IPアドレスを割り当ててあげればいいだけでした。 例えば下記のようにします。
php artisan serve --host 127.0.0.1 --port 8000
これで、TwitterAppsのCallBackアドレスは、
http://127.0.0.1:8000/{アクセスさせたいところ}
とします。
これでlocal環境でもCallBackを受けれるようになりました。
まとめ
そんなこんなで、無事Twitter OAuth認証が導入できました。
自分が今まで使ってたものを自分で実装してみるのって、なんかワクワクしますよね。
Laravel4.2でTwigを使う
こんにちは。
PHPの文法すらもよくわかっていない私ですが「勉強するにはまず作ってみることだ!」ということで、PHP & PHPのモダンなフレームワーク & MySQLの学習目的で、ちょっとしたWebアプリを作ってみようと思っています。
作るにあたって、せっかくならトレンドなフレームワークを使ってみようと思い、Laravel4.2を使うことにしました。
Laravelには標準的なテンプレートエンジンとしてBladeというものが用意されているのですが、ちょっと調べてみたところ、あまりイケてなさそう。
なぜイケてなさそうと思ったのかというと、エスケープが自動でなかったり、素のPHPも書けちゃうぜ的なところです。
普段は大規模な組み込み開発のエンジニアをやっているせいか「ヒューマンエラーが起きやすい」とか「きちんとした責務分割が強制されていない」ということが、どうしても気になっちゃうんですよね。これ不具合生まれやすいなーと思ってしまう。
ケース・バイ・ケースで一概に悪いこととは言い切れないのですが(特に後者)、個人的にはあんまり好みじゃないということで。
(Webアプリのことをよく理解していない初心者なので、考えが変わることもあるかもしれません)
Bladeじゃなかったら何を使う?ということで、Twigを使うことにしました。
エスケープ自動だし、素のPHPは基本的に書けないような感じみたいだし、イケてそう。
しかも、Laravelで簡単にTwigを使える「TwigBridge」というプラグインがあるらしい。
- TwigBridge
https://github.com/rcrowe/TwigBridge
導入は超簡単です。
GithubのREADMEを読むだけで十分だと思いますが、「英語を見ると蕁麻疹が出るぜ!」という人のために、一応手順を書いておきます。
(なお、私は英語が大の苦手です。勉強中)
導入手順
1. インストール
LaravelのProjectフォルダにあるcomposer.jsonのrequireに、下記のように追記します。
"require": {
"laravel/framework": "4.2.*",
"rcrowe/twigbridge": "0.6.*" //この行を追記
},
これでcomposer updateを実行。
2. configファイル(config/app.php)の編集
config/app.phpに下記の内容を追記します。
// config/app.php
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
・
・
・
'providers' => array(
・
・
・
'TwigBridge\ServiceProvider',
),
・
・
・
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
・
・
・
'aliases' => array(
・
・
・
'Twig' => 'TwigBridge\Facade\Twig',
),
準備はこれだけです。 簡単ですね!
使い方
Laravel上でBladeを使う時と同じ感覚で扱えます。 例えば、hello.twigファイルを使ってViewを表示するなら下記のように。
// app/routes.php
Route::get('/', function()
{
return View::make('hello');
});
値を渡すときも、Bladeを使う場合と同じでいけます。
// app/routes.php
Route::get('/', function()
{
return View::make('hello', array('name'=>'8miricd'));
});
Viewのほうも普通にTwigで書く場合と一緒。
// app/views/hello.twig
{% autoescape true %}
<html>
<head>
<meta charset="UTF-8">
<title>TwigTest</title>
</head>
<body>
Hello! {{name}}<br>
</body>
</html>
{% endautoescape %}
表示はこうなる。
簡単ですね!