見てはいけない黒歴史 in -The Rong's Caravan-
日記ログ コメント
About
黒歴史をリアルタイムで見られる貴重なサイト。
人間観察の悦びをあなたに・・・・・・

というのは冗談で、ただの趣味のサイトです。


管理人:ろんぐ
Since:2005/2/14
update:2017/09/20 「Livvon#8【新・メールアドレス認証】」
update:2017/09/20 「Livvon#8【新・メールアドレス認証】」
§Infomation§


ホテル、野宿の間となる「第三の選択肢」を実現するための、お手軽ルームシェアシステム

"Livvon"

(の投資家向け実演用プロトタイプ)開発中。
画像は現状着手してる部分。過程をお楽しみください。笑

※デザインに関しては「とりあえず機能だけ先に作る」という方針なので無頓着です。(笑)

*開発"最低"目標(9月中にプロトタイプ完成が最低ライン)*
9/15:ホスト情報更新部分
9/18:アクティベート(メールアドレス認証)
9/22:ホスト検索
9/25:予約ハンドシェイク
9/28:予約確認・キャンセル
9/30:ビジネスフローを再度書き出し、実演可能かどうか精査。
10/1〜:投資家探しと並行して、事業計画書及びテストを書く。

§Comment§
名前の非掲載


§Diary§
2017.9.20
Livvon#8【新・メールアドレス認証】

あー、びおら弾きたい...笑


今日は激烈に体調が悪く、起きてからずっと胃痛に悩まされてたので実は全然作業できてないです・・・・・・。
その遅れを取り戻すため、夜7時から活動開始しましたが、うーん・・・・・・。
まぁ、一応予定では金曜までに機能を完成させれば目的は果たせるんですけど、うーん。今日の進度が良さそうなら明日から筋トレ再開しようかなって思ってるんですけどね。


とか言いながらこんなもの食べてるのは頭おかしいとしか言えませんね。胃痛で苦しんだ後にデカ盛りラーメンはさすがに自殺行為としか思えまえんね!さすが自殺願望持ちは考え方が違う!
まぁ別に僕が苦しんでても誰も悲しみませんしね。俺がいま幸せならそれでいいのだ。(笑)

という冗談はさておき、体調が悪い時はとりあえずカロリー取って気分だけでも爽やかになった方がいいんじゃないかって感じはするんですよ!そう、これは滋養強壮を狙ったものなのである(・∀・)


・・・・・・さて、今日は昨日やったメールアドレス認証のまとめでも。



とりあえずメールアドレス認証のライブラリを使いたいなぁーって思ってたんですけど、軽く探してみたんですけど、ないんですよねこれが...

ということで、今回も自分でぽちぽち書こうかなぁと思うのです。
ただ、今回は一から書くんじゃなくて、Anonymousとか作った時の資産を使えばいいかな、って感じはします。
言うて仕組みはそんなに難しくないので、わざわざライブラリにするよーなものでもないのかなぁみたいな感じです。

一応、軽く実装の仕組みを喋りますと、なんかテキトーな文字列のトークンを生成してそれをユーザーテーブルにぶち込んで、そのトークンをくっつけたURLをメール送信し、それをクリックしてもらうことで確認ができる、ってわけですね。
トークンはメール受信者以外知り得ない情報なので、これで認証ができます。ついでに生成日時なんかをテーブルに突っ込んでおけば時間制限とかできますね。
将来的には時間制限をつけるかも知れませんが、今回は時間制限をつけないこととします。


過去の資産を流用しようと思ったんですが、どうやらLaravel5.4になってちょっと仕様が変わったっぽいので、それに合わせて書き換える感じになりそーですね。


とりあえず簡単に実装してみました。
データベースに「確認するEmailの対象」みたいなカラムは別に入れなくてもいいんですけど、メンテナンス性のためにとりあえず入れておくことにします。



まず、メールの環境設定ですね。今回はgmail使います。さすがに本番で使うつもりないですけど笑


MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=ID@gmail.com
MAIL_PASSWORD=パスワード
MAIL_ENCRYPTION=tls

調べてるといろんなサービスが使えるみたいですが、プロトタイプの時点では普通にsmtpで通します。
ただ、将来的には別のものを使う可能性がありそうですね。レスポンス悪いし...



//emailを渡すと、ハッシュ付きのメールを送信する
private static function send_email_token($email){
    $token=str_random(60);
    DB::table('users')
           ->where('id', Auth::user()->id)
        ->update([
            'email_confirm' => 0, //メール認証を”未完了”にする
            'confirmation_email' => $email,
            'confirmation_token' => $token,
            'confirmation_created_at' => new \DateTime()
    ]);
    Mail::to($email)
        ->queue(new MailCertification($token));
}

で、こちらがメール送信部の実態ですね。色々ゴミデータが入ってますがまぁ気にしない方向で。

なんとなく汎用性を目指して静的関数で宣言してます。実際メールアドレスさえあればいいわけですしね。とりあえず認証系なので認証系のコントローラーにぶち込んでやりましたが、別にクラス作ってもよかったかも知れませんね。
やってることは簡単です。ランダムに60文字生成させて、それをDBに登録して、メール送信してもらってるだけです。
いつのまにかメール送信がより書きやすくなってます。5.3からみたいですね。toに宛先を入れて、あとはメール送信用のクラスを作ってくれって感じです。たいへん管理がしやすいです。よき。



class MailCertification extends Mailable
{
    use Queueable, SerializesModels;

    protected $token;//トークン

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->from('example@example.com')
                ->view('Emails.MailCertification')
                ->subject('【Livvon】メールアドレス認証')
                ->with([
                    'token' => $this->token
                ]);
    }
}

で、これが実態ですね。

$ php artisan make:mail MailCertification

たぶんこれでベースが勝手に生成されます。基本的にbuild()をいじりますが、今回はトークンが絶対に渡されるので、コンストラクタでそれを登録しています。
あとはビューに普通に渡せばいいだけです。おおらくちん。



メールアドレス認証を行います。<br>
以下のURLをクリックして変更を確定してください。<br>
<br>
{{ url('cert/'.$token) }}
<br>
<br>
※心当たりがない場合は無視して下さい。ご迷惑をおかけしました。

ビューはこんな感じです。そのまんまですね。




実際の画面だとこんな感じです。ほんとにすぐできちゃいましたね。




    public function check_token($token){
        $record = DB::table('users')->where('confirmation_token', $token);
        $userinstance = $record->first();
        if(empty( $userinstance )){
            //トークンが異なっている
            return view("Error.mailcert");
        }

        //トークンが一致、情報を更新する
        $record->update([
            'email_confirm' => 1, //メール認証を”完了”にする
            'email' => $userinstance->confirmation_email,
            'confirmation_email' => null,
            'confirmation_token' => null,
            'confirmation_created_at' => null,
        ]);

        return view('auth.mailcertfinish');
    }

せっかくなので、認証実行部分も。かなーーり簡単に作ってますけどこれで充分だと思います。
トークンで検索して、ヒットしたらそれを認証すればいいです。ヒットしなかったらなんかおかしいのでエラー画面に飛ばす。

トークンでの検索は、トークンにインデックスつけないと激マズなので、場合によってはパラメーターにemailあるいはidをつけるとかのチューンナップをしてもいいかも知れませんね。僕はめんどかったのでやめました(笑)



とりあえずメールアドレス認証はこんな感じで作れます。メール送信もすごい管理しやすくなった感じしますね。
ハンドシェイクなどでメールは大活躍するので、これだけ使いやすいと作りがいもありそーですね(笑)(笑)


んじゃ、がんばってノルマ達成に向けてプログラミングしますぞ(・∀・)

2017.9.19
Livvon#7【Timeクラス(自作クラス)】

昨日スパなんかにいったせいで予定が大幅に遅れていますので、今日は筋トレなんかせずに予定を回復させる方針で行きたいと思います。これで3時間ぐらいは確保できますね。


いま頭を悩ませてる問題のひとつとしてTime型を扱えるライブラリがないということです。
軽く探してみたんですが、日付時刻ならCarbonという人気のライブラリが標準で付属しているみたいなので、それを使ってみようと思うのですが、時刻だけとなるといい感じのものがなかったので、財産として作ってみることにしました。


やりたいことは以下です。


・文字列表記と、配列の両対応
・簡単なバリデーション
・コンストラクタに値をぶっ込んだ時点で全ての準備が整う


ということで、突貫工事で作ってみたわけです。



/*時間情報を扱うクラス*/
class Time{
    private $hh = null;
    public function get_hh(){
        return $this->hh;
    }
    private $h = null;
    public function get_h(){
        return $this->h;
    }

    private $mm = null;
    public function get_mm(){
        return $this->hh;
    }
    private $m = null;
    public function get_m(){
        return $this->m;
    }

    private $ss = null;
    public function get_ss(){
        return $this->ss;
    }
    private $s = null;
    public function get_s(){
        return $this->s;
    }

    public function get_Array(){
        return array($this->h,$this->m,$this->s);
    }
    public function get_Array_hm(){
        return array($this->h,$this->m);
    }
    public function get_Array_00(){
        return array($this->hh,$this->mm,$this->ss);
    }
    public function get_Array_hm_00(){
        return array($this->hh,$this->mm);
    }

    private $string =null;
    public function get_String(){
        return $this->string;
    }
    private $string_hm =null;
    public function get_String_hm(){
        return $this->string_hm;
    }


    public function __construct($var) {
     if(is_array($var)){
         $this->generate_from_Array($var);
     }else{
         $this->generate_from_Time($var);
     }
    }

    private function initialize(){
        $this->hh = "00";
        $this->h = 0;
        $this->mm = "00";
        $this->m = 0;
        $this->ss = "00";
        $this->s = 0;
    }
    private static function addingZero($int):String{
        if(empty($int)){return "00";}
        if(($int+0)<10){
            return "0".($int+0);
        }
        return (String)$int;
    }
    private static function stripZero($str):int{
        if(empty($str)){return 0;}
        return $str+0;
    }

    private function generate_hms($array_hms){
        $this->hh = Time::addingZero($array_hms[0]);
        $this->h = Time::stripZero($array_hms[0]);
        $this->mm = Time::addingZero($array_hms[1]);
        $this->m = Time::stripZero($array_hms[1]);
        if(isset($array_hms[2])){
            $this->ss = Time::addingZero($array_hms[2]);
            $this->s = Time::stripZero($array_hms[2]);
        }
    }

    private function generate_string(){
        //配列に格納された値から文字列を生成
        $this->string = $this->hh.":".$this->mm.":".$this->ss;
        $this->string_hm = $this->hh.":".$this->mm;
    }

    public function generate_from_Time($str){
        if(!preg_match('/\A([0-9]+:[0-5]?[0-9]{1}|[0-9]+:[0-5]?[0-9]{1}:[0-5]?[0-9]){1}\z/', $str) ){
            //正規表現に一致しないため、falseを返して終了。
            return null;
        }
        $this->initialize();//正常なデータなので、初期値を代入
        $this->generate_hms(explode(":", $str));
        $this->generate_string();
    }

    private static function is_integer_check($var){
        if(is_int($var)){return true;}
        if(ctype_digit($var)){return true;}
        return false;
    }
    public function generate_from_Array($array){

        //数値かどうかのバリデーション
        if(!Time::is_integer_check($array[0])){return null;}//「時」がnullのパターンは存在しない(「分」はnullを受け付ける)
        if(isset($array[1]) && !Time::is_integer_check($array[1])){return null;}//「分」はnullと数値を許容
        if(isset($array[2]) && !Time::is_integer_check($array[2])){return null;}//「秒」も同様

        //正常値かどうかのバリデーション
        if($array[0]<0){return null;}
        if(isset($array[1])){ if(!(0<=$array[1] && $array[1]<60)){return null;} }
        if(isset($array[2])){ if(!(0<=$array[2] && $array[2]<60)){return null;} }

        $this->initialize();//正常なデータなので、初期値を代入
        $this->generate_hms($array);
        $this->generate_string();
    }
}


class TimeComparer{
    private $time1;
    private $time2;
    public function __construct(Time $time1,Time $time2) {
        $this->time1 = $time1;
        $this->time2 = $time2;
    }

    public function is_confirm(){
        //どちらか片方が未指定であれば通す
        if($this->time1->get_String() === null){return true;}
        if($this->time2->get_String() === null){return true;}

        //時間1>時間2は問題なのでエラー
        if($this->time1->get_h() > $this->time2->get_h()){return false;}
        if($this->time1->get_h() == $this->time2->get_h()){
            //「時」が共に同じなら「分」で比較
            if($this->time1->get_m() > $this->time2->get_m()){return false;}
        }
        return true;
    }
}

こんな2つのクラスを半日かけて作ってみました。ちなみに使う範囲以外でちゃんと動作確認はしてません。(!?)
とりあえず、時刻を扱うインスタンスをとりあえずコンストラクタにぶっこめば、関連した情報を勝手に作ってくれる、っていうイメージで作ってます。

ただ、キャスト回りでだいぶ迷走してて、ほんとにこれが正解なのかよくわからない感じになってますが、まぁ僕が使う用だし...笑



ちなみに、プログラミングのお作法に全く則っていない書き方してるので、プロの方が見たら怒られる書き方なのでこんなプログラマにならにようにしてくださいね←


やー、twitterとかではちょくちょくつぶやいた気がするんですけど、僕はどうやらプログラムを書くのが嫌いなようだ(笑)
別にプログラムが好きで書き始めたわけじゃないですからね。最初から一貫して「手段」でしかないし。手っ取り早く成功するには自分でプログラム書いて面白いサービス作ればいいじゃんって思って勉強しただけですしね。それが今になって活きてるのはおもしろいですけど。当初と全然見据えるルート変わっちゃいましたけど(笑)
最初は無料のSNS作って、同時進行で演奏してみたとかで売名行為を働いて、自らが広告塔になることで拡散を狙おうと思ってたんだけどなぁ、、、
まぁ僕のパーソナリティが色んな人に全否定されちゃったしね、しょうがないね


はやくビジネスのことだけに頭回せるようになりたいなぁほんと。コード書く才能はないわ自分。バグフィクスきらいだし。(笑)



とりあえず、トップページに載せてる通り、一日でアクティベーションを完成させました。まぁ言うて元々の基盤は作ってましたし、あとはメールアドレス認証を完成させるだけで良かったですしね。



お次はホスト検索・・・・・・つまり、宿の検索です。GoogleMapsAPIとか絡むので、ぶっちゃけ2日で完成とか無理だと思ってます()
その次の予約ハンドシェイクも、ビジネスフローが若干ふんわりしてたような気がしてて、これも以外なところで引っかかりそうですね。
ただ、ここまで作っちゃえばプロトタイプとしては上出来で、最悪キャンセルは実装しない、という思い切った選択もできますね。まぁ一応作っておくつもりではいますけど・・・・・・。

2017.9.18
高級スパでひとやすみ。

ということで、麺屋武蔵でがっつり食べてから、池袋にありますRESTA(レスタ)というスパで寛ごうと思いましてね。
サンシャインの真ん前にある高級スパです。そう、高級スパ。


いや・・・・・・りょうや君がなんか行きたがってて・・・・・・。
ここでノンスタイルを見に行きたいとか言ってくれればコロンちゃんに会えたかも知れないのにね(笑)(笑)




スパの写真なんか撮れるわけないので、ロビーの写真でも。


高級スパなんて一人じゃ絶対来ないし、そもそもスパ自体行かない人なんで、色々新鮮でしたね。
サウナとか本格的に挑戦してみてみました。きつかったです。体重そんなに減りませんでした。はて????←


っていうか、見た目やばかった時期より明らかにマシなはずなのに体重めっちゃ増えてたんだけど!!なぜだ!!!!65kg行きそうなんだけど!!!!
うーん、筋トレが悪いのか!?分厚い脂肪の裏で何気に筋肉が育ってきているのか!?!?じゃあ目に見える形で出てくれよ!!!


さすがに同様を隠しきれなかったが、昼に食った500gのラーメンとか、サウナ前にがぶ飲みした水が悪いということにしておこう・・・・・・。



しかしまぁ、人と入る温泉もなかなかに楽しいものですね。僕もハマりそうである(・∀・)楽しかったからまた誘ってね。今度は横浜に来てもいいぞ(笑)(笑)(笑)



>>もっと読みたい


Contents
日記
過去ログです。
旅行レポートなどもこちらに置いています。

音楽素材
RPGツクール向けの音楽素材です。
現在の素材数は187曲です。

Fashion研究学Note
地雷を踏まないファッション研究学。低予算でディスられないファッションを目指します。

写真素材
旅行中、無駄に撮った写真を素材として並べています。
現在2600枚ほど。
そのうち更新します。

Products
Anonymous(仮)(β)
"SNS疲れ"からの開放を目指したtwitterインスパイアの匿名SNS
Musel
オーケストラ楽曲の編成表データベースです。(将来的にリファイン予定)

Commnication
The 人間観察(掲示板)
管理人は基本チェックしてません。←
旧BBS
一応残しておきます。

Other

Author
twitterも気軽にフォローミー!おすすめはしない!笑