2016-05-05 9 views
1

私はモバイルアプリケーションのバックエンド部分で作業しています。バックエンドはRESTfulなAPIになります。私の主な質問 - 認証/認証ユーザーです。Laravel 5承認用にFacebookを使用しているモバイルアプリケーションのAPI承認

私たちはモバイルアプリケーション側でFacebook承認(iOS用Facebook SDK)を使用します。ここでの主な質問は、バックエンド側でFacebookから取得できるデータのみを使用して認可を実装する方法です。

誰かがすでにいくつかの解決策を持っているか、このタスクのいくつかの例を提供することができますか?

  1. ユーザープレスアプリケーションの「ログインFBと」ボタンを、彼が接続

  2. ユーザーが戻るのを承認FBへのリダイレクトを取得:

    私は、このプロセスを想像することができますFBからのデータを含むアプリケーション(ユーザーのFacebook ID、一部のユーザーデータ、認証トークン)

  3. アプリケーションはこのデータをAPIに送信し、ユーザーの登録/認証を試みます

  4. APIは、アプリケーションがAPIにリクエストを送信する際のチェックのために、ユーザーがこのトークンを使用して、トークンの承認を保存し、

私が修正するか、このロジックが間違っているのでしょうか?アドバイスをしてください。可能であれば、いくつか例を挙げてください。

はまた、私はそれが私の状況に参考になる...

答えて

1

プロセスが正常に見えることを確認this guyを見つけましたが、いませんよ。追加する必要があるのは、API呼び出しを行うときにLaravel CSRF tokenです。

+0

良いアドバイス。また、公式サイトのCSRF保護についての情報もあります:https://laravel.com/docs/master/routing#csrf-protection –

1

だから、この問題についていくつかの調査を行い、いくつかの結果が得られました。認証プロセスは次のようになります。クライアント上

  • がログインしてのOAuth2コードを取得するにはFacebookのAPIを使用してください。
  • このコードをアクセストークンに交換します。
  • APIで として要求Facebookのトークンを含む私のAPIからのアクセストークンを、パラメータ

  • は、アクセストークン要求を受信します。

  • Facebookのアクセスを使用して/私のFacebookのグラフにリクエストを行い トークン

  • Facebookのユーザーが存在することを確認し、一致私の データベース

  • でユーザーに自分のアクセストークンを作成します。 、それを保存して、私はMIGを作成し、すべてのこの時点から使用

最初になるように、それをクライアントに返しますユーザーテーブルの比:

<?php 

use Illuminate\Database\Schema\Blueprint; 
use Illuminate\Database\Migrations\Migration; 

class CreateUsersTable extends Migration 
{ 
    /** 
    * Run the migrations. 
    * 
    * @return void 
    */ 
    public function up() 
    { 
     Schema::create('users', function (Blueprint $table) { 
      $table->increments('id')->unique(); 
      $table->bigInteger('facebook_id')->unique(); 
      $table->string('name')->unique(); 
      $table->string('email')->unique(); 
      $table->string('password')->nullable(); 
      $table->string('accessToken')->nullable(); 
      $table->rememberToken(); 
      $table->timestamps(); 
     }); 
    } 

    /** 
    * Reverse the migrations. 
    * 
    * @return void 
    */ 
    public function down() 
    { 
     Schema::drop('users'); 
    } 
} 

は、その後、私は完全に簡単Laravelと内腔へのFacebook SDKのV5を統合するための手段、試験パッケージであるプロジェクトにLaravelFacebookSdkを添加しました。

は、それから私は、認証のためのいくつかの敗走を追加しました:

Route::group(['prefix' => '/auth' /*, 'middleware' => 'throttle:10,5'*/], function() { 
    Route::get('/', '[email protected]'); 
    Route::get('/base', '[email protected]'); 
    Route::get('/fb', '[email protected]'); 
    Route::get('/vk', '[email protected]'); 
}); 

そして、これらのルートを処理するためのコントローラを作成しました:

namespace App\Http\Controllers; 

use App\Http\Requests; 
use Illuminate\Http\Request; 
use Illuminate\Support\Facades\Auth; 
use SammyK\LaravelFacebookSdk\LaravelFacebookSdk; 
use App\User; 

class ApiAuthController extends Controller 
{ 
    protected $baseAuthFailedResponse = [ 
     'status' => false, 
     'message' => 'Base authentication failed' 
    ]; 
    protected $facebookAuthFailedResponse = [ 
     'status' => false, 
     'message' => 'Facebook authentication failed' 
    ]; 
    protected $vkAuthFailedResponse = [ 
     'status' => false, 
     'message' => 'VK authentication failed' 
    ]; 

    /** 
    * Echo function 
    * 
    * @param Request $request 
    * @return \Illuminate\Http\JsonResponse 
    */ 
    public function index(Request $request){ 
     return response()->json($request); 
    } 

    /** 
    * Authorise user with base authorisation using email and password 
    * 
    * @param Request $request - expects fields: email, password 
    * @return \Illuminate\Http\JsonResponse 
    */ 
    public function baseAuth(Request $request){ 
     $isAuthorised = Auth::attempt(
      array(
       'email' => $request->input('email'), 
       'password' => $request->input('password') 
      ) 
     ); 
     if ($isAuthorised){ 
      return response()->json(Auth::user()); 
     } 

     return response()->json($this->baseAuthFailedResponse); 
    } 

    /** 
    * Authorise user using facebook accessToken received in the request 
    * 
    * @param Request $request - expects fields: accessToken, username, fullName, email 
    * @return \Illuminate\Http\JsonResponse 
    */ 
    public function facebookAuth(Request $request, LaravelFacebookSdk $fb){ 
     if(!Auth::check()){ 
      // Receive access token request. 
      $accessToken = $request->input('accessToken'); 
      // Make a request to the /me Facebook graph using the facebook access token 
      try { 
       $response = $fb->get('/me?fields=id,name,email', $accessToken); 
      } catch(\Facebook\Exceptions\FacebookSDKException $e) { 
       $this->facebookAuthFailedResponse['details']['message'] = $e->getMessage(); 
       $this->facebookAuthFailedResponse['details']['error_code'] = $e->getCode(); 

       return response()->json($this->facebookAuthFailedResponse); 
      } 

      // Verify that the Facebook user exists and match to a user in my database or create new one 

      // Convert the response to a `Facebook/GraphNodes/GraphUser` collection 
      $facebookUser = $response->getGraphUser(); 

      // Create the user if it does not exist or update the existing entry. 
      // This will only work if you've added the SyncableGraphNodeTrait to your User model. 
      $user = User::createOrUpdateGraphNode($facebookUser); 

      Auth::login($user, true); 
     } 

     return response()->json(Auth::user()); 
    } 

    public function vkAuth(Request $request){ 
     return response()->json($this->vkAuthFailedResponse); 
    } 
} 

また、あなたは私がLaravelFacebookSdkが提供する機能$user = User::createOrUpdateGraphNode($facebookUser);を使用見ることができるように。モデルで使用するには、SyncableGraphNodeTraitを実装する必要があります。この方法により、Facebookから直接返されたデータを簡単に取得し、ローカルデータベースで作成または更新することが容易になります。

<?php 

namespace App; 

use Illuminate\Foundation\Auth\User as Authenticatable; 
use SammyK\LaravelFacebookSdk\SyncableGraphNodeTrait; 

class User extends Authenticatable 
{ 
    use SyncableGraphNodeTrait; 

    /** 
    * The keys of the array are the names of the fields on the Graph node. 
    * The values of the array are the names of the columns in the local database. 
    */ 
    protected static $graph_node_field_aliases = [ 
     'id' => 'facebook_id' 
    ]; 

    /** 
    * The attributes that are mass assignable. 
    * 
    * @var array 
    */ 
    protected $fillable = [ 
     'name', 'email', 'password', 
    ]; 

    /** 
    * The attributes that should be hidden for arrays. 
    * 
    * @var array 
    */ 
    protected $hidden = [ 
     'password', 'remember_token', 
    ]; 
} 

解決方法についてご意見がありましたら、コメント欄にご記入ください。

UPD:認証プロセスの説明は、this topicです。また、this topicも非常に便利でした。公式サイトからAPI descriptionthis topcで見つけたユーザーを簡単に覚えておく方法。そしてそこにはAPI servers on Laravelに関する有用な情報がいくつか見つかりました。そして良い説明についてauthentication with tokens

関連する問題