一般的なログイン サイトの仕組み
一般的なログインサイトの仕組みを自作してみました。
開発環境はLaravelを利用しているので、ユーザID(メールアドレス)、パスワードをDBに挿入、認証させるのはフレームワークの機能なので省いて、全体のサービスとしての仕様の概要を話します。
一般的にユーザーID、パスワード認証の仕組みを実装しようとすると以下の機能が必要になります
・ユーザ登録をする
・ログインをする
・メール認証(ユーザ登録で登録されたアドレスが本当に正しいアドレスかの確認)
・パスワード忘れ
・サービスの退会処理
ユーザ登録してログインするだけならすごく簡単なのですが、それに付随する機能を作成するのが面倒です。
自分の場合他のfacebookなどのSNSアカウントでもログインできるようにしているので、他のログインシステムと整合性を取るための仕組みが必要でした。
- シーケンス、フローチャート
1, ユーザID(メールアドレス)、パスワードをサーバに送信
これは簡単にこの2つをサーバ側にPOSTするだけで問題ありません(javascriptなどでチェックはしてください。)
2, DBに仮登録
postされたデータをDBに挿入、メールでのURL認証がまだなので、その辺はフラグ操作で仮登録のフェーズに設定してください。
一般的なSNSではユーザ登録後に認証URLがメールで送信されてきて、それをクリックしたら完了というのが多いです。これは登録したメールアドレスが本当に本人のものかを確認するためのチェックです(当たり前です)
なので登録したメールアドレス+日付などの文字列のMD5でユニークな認証キーを作成して、それを登録ユーザにメール送信します。
http://3ps-net.com/chk?hash=xxxxxxxxxxxxxxxxxxxxx のような感じになります。
もちろんサーバ側はユニークな認証キーとユーザIDを紐づけて保存します。
3, 認証URLの選択
登録者は届いたメールの認証URLを選択します。
嘘のメールアドレスを登録しない限り、登録したメールアドレス(自分)に認証URLは届きますよね。
4, 正式に登録完了
認証キーのURL(GET)にアクセスがあったのでサーバ側は認証キーを検索、ユーザIDを求めて、このユーザIDは正式にユーザ登録が完了したことになります。
以上です。
あまり既存の資料を参考にせず、自分で考えたので間違いがあれば教えて頂ければ嬉しいです。
3PSの独自ログインの機能を追加
他のSNSアカウントに寄生していた。3PSですが、3PSの独自アカウントを登録できる仕組みを追加しました。
個人的にはどのSNSのアカウントでもユーザが任意に識別できればこだわりはないですが、各SNSのアカウントを保有していない人も出てくるだろうと思い追加しました。
プログラム的にはログイン回り自体の機能はLaravelのフレームワークを使えば簡単なのですが、パスワードを忘れた、メール認証の確認メールの送信、他のSNSアカウントとの影響・・・などなどログインの機能の周りの部分を作るのがけっこう手間(時間がかかる)かかりました。DBの構造は独自アカウントの導入も考えて他ので変更しなかった、この辺はうまくハマってくれてよかった
3PS
やっと最低限の機能を実装が完了してきたので、今回は今自分が作成しているサービス、3PSの説明を書きたいと思います。
- どういうサービス??
ユーザー間で3Dプリンターを共有して物づくりを楽しもうというサービス
3Dプリンターを持ってるけど使っていない時間がたくさんある。3Dデータを作成したけど出力するための3Dプリンターを持っていない。
この2人をマッチングさせるためのサービスです。 物づくりのシェアリング サービスです。
- 3PS自体の利用料金は?
無料です。
- 3Dデータの出力に費用は必要ですか?
3Dデータの出力にかかる費用は、3Dプリンターの保有者と3Dデータの出力希望者の間で決めてください。
例えば、3Dプリンター保有者が使っていない時間で他の人のデータを出力する場合
このような3Dプリンターのジョブを3PS上に作成します。(例)
3Dデータの出力希望者はこの掲示を見て興味があれば出力依頼をだします。
逆に、3Dデータを作成した出力希望者も自分から3PS上に出力依頼を書き込み、出力してくれる3Dプリンターの保有者を探すことができます。
このとき、どの素材?どのぐらいのサイズ?どのくらいの料金?を明確に書くことで円滑に連絡がとれます。
- 安く出力できるの?
現在、外部出力のサービスでは、100mm四方の立体で2~数万円の出力費用が必要になるところがほとんどです。(その分、光造形などの高クォリーティーな出力方法になります)
3PSではユーザー間で出力費用を決めます。より安く、高クォリーティーな出力が可能なユーザーを探してください。1時間、数百円で出力可能なユーザがを見つけることも可能かもしれません。
今後、3PSは3Dデータ出力コミュニティーの場としてのサービスを中心により使いやすいインターフェイス、機能を追加していきたいと思います。
ユーザ間でファイルの共有とジョブ(3Dプリンターでできること)をSNSでシェアできるようにしました。
- ユーザ間でのファイル共有
3Dデータの出力希望者、3Dプリンターの保有者に出力依頼する場合、必ずデータの受け渡し方法が必要になります。メールや既存のファイル共有ストレージを利用していただいてもかましませんし、3PSのメッセージ(連絡用)にファイルを共有する機能を追加しましたので、こちらを利用していただいてもかまいません。
ファイル共有はメッセージのやり取りをしている相手のみダウンロードが可能です。
細かい話として、ファイルのアップロードは公開ディレクトリ以外のユーザーディレクトリに保存し、ダウンロード時は直リンクではなく、ユーザIDとアップロードIDなどで保有者と送信先をチェック後、サーバー側からダウンロードさせる(Content-Type application/force-download)で行っています。ファイルのアップサイズは3Dデータを送信することを考え1ファイル50MBまでアップ可能で1週間後に自動的に削除されます(サーバー容量の都合上ご理解ください)
※念のため重要なファイルなどはzip圧縮などでパスワードをかけて送信してください。仕事でもどんなに厳重なファイル管理状態でも重要ファイルにはパスワードかけてました(私) 念には念をいれて。
- 公開したジョブ情報をSNSにシェアできる機能を追加しました
公開したジョブ情報を各SNSでシェアできるようにしました。 公開ジョブは3PS上で一覧表示されますが、それ以外にもユーザが自分からシェアして外部に広告できるようになります。
皆様に・・
3PSはまだスタートアップして間もないサービスです。サイトのユーザー数はまだほとんどいません。機能面でもコミニティーとしての最低限ができている程度だと思っていますが、開発している本人はやる気満々です。
今は3Dプリンター保有者でジョブに対して中々出力希望の連絡が来ないという方もでてくると思いますがしばらく、ユーザーが増えるまでは忍耐強く待っていただければ嬉しいですm(_ _)m
■今後の追加機能
・出力者の出力場所を地図上に表記できるようにしたい。(希望者のみ)
近場の出力者を見つければ当日納品も可能になるかも・・・
・フォーラムやコミニティーの充実
・ジョブ情報の検索機能(ユーザが増えれば必然的に必要になる)
・作品などをアップできるギャラリーの作成
・出力希望者からもジョブを作れるようにしたい
etc・・・・
3PS ジョブのBookmarkの機能を追加しました
3Dプリンター保有者のジョブ(出力ジョブ)に対して気になるけど、いきなり連絡とるのはちょっとという時のためにブックマーク(お気に入り)に登録できる機能をを追加してみました。
"出力依頼"->"ジョブ検索"->"ジョブ詳細"
ジョブの内容で少し気になる記事があればブックマークに登録して、そのあと吟味した上で連絡を取るなどできます。
ブックマークは最大30個まで保存できます。
登録したブックマークは"出力依頼"->"Bookmark"に登録されます。
次は、少しデザインをもう少しまともなもに修正しようかと思います。ログイン後の画面、冷静に見ればかなりダサいです(><
その次にユーザー間でファイルの出力ファイルの受け渡しができる機能を追加しようかな、出力依頼者が3Dプリンター出力者にファイルを渡す方法が必要になってきますからね。
Laravel Socialiteを利用してFacebook, Twitter, Google+の認証処理を共通化できた
現在、作成している3PS(3Dプリンター共有サービス)はFacebook, Twitter, Google+のアカウントを持っている人であればだれでもご利用できます。 後日ですが各SNSアカウントを持ってなくてもメールアドレス、パスワード登録で独自アカウント作成の機能も追加します。
各SNSのログイン認証の処理はLaravelのSocialiteライブラリを使ってやっています。
Socialiteは各SNSのログイン認証の処理を共通化してほぼ同じコードでやってくれるという凄まじく便利なライブラリです。この3PSのように他のSNSアカウントを利用(寄生?)してるサービスでは神様のようなライブラリです。Socialiteを利用して3社のログイン認証の開発で3時間程度かかったとすると、もしこれが無ければ、10倍ぐらい開発で時間かかったと思います。(各SNSのSDKを落として仕様を理解したりの時間)
で! どんな風に使うといえば
参考にしたサイト
madroom project: Laravel SocialiteでFacebookとTwitterの認証をしてみた
■composerでSocialiteのインストール
composer.json
{ "name": "laravel/laravel", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "type": "project", "require": { "laravel/framework": "5.0.*", "facebook/php-sdk": "dev-master", "barryvdh/laravel-debugbar": "~2.0", "laravelcollective/html": "~5.0", "intervention/image": "dev-master", "intervention/imagecache": "~2.1" "laravel/socialite": "~2.0", //この行を追加 }, //省略 }
■各SNSのAPIキーを取得
これは各SNSのディベロッパー登録をして取得してください。 省略
■services.phpにAPIキーを登録
app/config/services.php
services.phpに取得したAPIキー、シークレットキーを記述。
redirectには認証後にコールバックされるurlを記述します。
'facebook' => [ 'client_id' => 'xxxxxxxxxx', 'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'redirect' => url('/facebook/callback'), ], 'twitter' => [ 'client_id' => 'xxxxxxxxxx', 'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'redirect' => url('/twitter/callback'), ], 'google' => [ 'client_id' => 'xxxxxxxxxx', 'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'redirect' => url('/google/callback'), ],
■処理部分
routes.php
//Facebookログイン認証のURL Route::get('/facebook', 'FacebookController@getLogin'); //認証後にコールバックされるURL Route::get('/facebook/callback', 'FacebookController@getCallback');
FacebookController.php
ログイン認証時、認証後に実行する処理などを記述する
<?php namespace App\Http\Controllers; use Laravel\Socialite\Contracts\Factory as Socialite; //省略 class FacebookController extends Controller { /** * @var Socialite */ protected $socialite; /** * * */ public function __construct(Socialite $socialite) { $this->socialite = $socialite; } /** * * */ public function getLogin() { //ここで各SNSを設定する return $this->socialite->driver('facebook')->redirect(); } /** * * */ public function getCallback() { //認証後にここがコールバックされます。 $fuser = $this->socialite->driver('facebook')->user(); $fuser->getId(); //facebookのユーザID $fuser->getName(); //facebook上の名前 $fuser->getEmail(); //メールアドレス //あとはお好きに!! //facebookのIDと自分のサービスのユーザIDを紐づける処理などを記述してください $user = User::where('app_id', $fuser->getId())->first(); if(!$user) { //自分のuserテーブル登録されていないユーザなので新規ユーザ //ユーザ登録の処理 } else { //facebookのIDからユーザアカウント(自分のサービス)を取得できたのでログインの処理をする //ログイン Auth::login($user); } } }