适用于使用Facebook进行授权的移动应用程序的Laravel 5 API授权 [英] Laravel 5 API authorization for mobile applications which uses Facebook for authorization

查看:80
本文介绍了适用于使用Facebook进行授权的移动应用程序的Laravel 5 API授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为移动应用程序开发后端部分.后端将是RESTful API.对我来说,主要问题-是授权/身份验证用户.

I'm working on back-end part for mobile application. The back-end will be a RESTful API. The main question for me - it's authorization/authentication users.

我们将在移动应用程序端使用Facebook授权(iOS的Facebook SDK).这里的主要问题是:如何仅使用从Facebook获得的数据在后端实现授权?

We will use the Facebook authorization (Facebook SDK for iOS) on the mobile application side. The main question here is: how to implement authorization on back-end side using only data we can get from Facebook?

也许有人已经获得了一些解决方案,或者可以提供一些示例来完成此任务?

Maybe someone already got some solutions or can provide some examples for this task?

我可以将这个过程想象为:

I can imagine this process as:

  1. 用户在应用程序中按下使用FB登录"按钮,然后将其重定向到FB,并在此批准连接

  1. User press the "Login with FB" button in the application and getting the redirect to FB, where he approve the connect

用户使用FB中的一些数据(用户Facebook ID,一些用户数据和授权令牌)返回应用程序

User returns to the application with some data from FB (user Facebook ID, some user data and authorization token)

应用程序将此数据发送到API并尝试注册/验证用户

Application sends this data to the API and trying to register/authenticate the user

API保存授权令牌,然后在应用程序将请求发送到API时使用此令牌检查用户

API save the authorization token and then use this token for check the user when application send the requests to API

我是正确的还是这个逻辑是错误的?请提出建议,并在可能的情况下提供一些示例.

Am I correct or this logic is wrong? Please advise, and if possible provide some examples.

我也找到了这个家伙,但不确定对我的情况会有所帮助.

Also I'm found this guy, but not sure it will be helpful in my situation...

推荐答案

因此,对该问题进行了一些研究,现在有了一些结果.现在,身份验证过程如下所示:

So, done some research about the issue and now have some results. The authentication process now looks like this:

在客户端上:

  • 使用Facebook API登录并获取OAUTH2代码.
  • 将此代码交换为访问令牌.
  • 从我的API请求访问令牌,包括Facebook令牌为 参数
  • Use the Facebook API to login and get an OAUTH2 code.
  • Exchange this code for an access token.
  • Request an access token from my API, including the Facebook token as a parameter

在API上

  • 接收访问令牌请求.

  • Receive access token request.

使用facebook访问向/me Facebook图发出请求 令牌

Make a request to the /me Facebook graph using the facebook access token

验证Facebook用户存在并与我的用户匹配 数据库

Verify that the Facebook user exists and match to a user in my database

创建我自己的访问令牌,将其保存并返回给客户端 从现在开始使用

Create my own access token, save it and return it to the client to be used from this point forward

首先,我为用户表创建了一个迁移:

First of all I created a migration for user table:

<?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');
    }
}

然后,我在项目中添加了 LaravelFacebookSdk ,该项目经过完全单元测试,可轻松集成Facebook将SDK v5集成到Laravel和Lumen中.

Then I added LaravelFacebookSdk to the project which is fully unit-tested package for easily integrating the Facebook SDK v5 into Laravel and Lumen.

然后我添加了一些验证路线:

Then I added some routs for authentication:

Route::group(['prefix' => '/auth' /*, 'middleware' => 'throttle:10,5'*/], function () {
    Route::get('/', 'ApiAuthController@index');
    Route::get('/base', 'ApiAuthController@baseAuth');
    Route::get('/fb', 'ApiAuthController@facebookAuth');
    Route::get('/vk', 'ApiAuthController@vkAuth');
});

并创建了一个控制器来处理这些路由:

And created a controller to handle these routes:

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直接返回的数据并在本地数据库中创建或更新数据变得很容易.

Also, as you can see I used a function $user = User::createOrUpdateGraphNode($facebookUser); which provided by LaravelFacebookSdk. To use it in our model we should implement the SyncableGraphNodeTrait. This method really makes it easy to take data that was returned directly from Facebook and create or update it in the local database.

<?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',
    ];
}

如果有人对解决方案有任何说明,请在评论中提供.

If someone have any notes about solution, please provide it in comments.

UPD :我从此主题非常有用.官方网站上的 API描述.如何轻松记住我在通过令牌进行身份验证

UPD: The auth process description I'm got from this topic. And also this topic was very useful. An API description from the official site. How to easy remember the user I found in this topc. And there I found some useful information about API servers on Laravel. And good description about authentication with tokens

这篇关于适用于使用Facebook进行授权的移动应用程序的Laravel 5 API授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆