dongou3286 2016-09-16 12:57
浏览 133
已采纳

Laravel 5.3和护照。 尝试为API创建单个客户端

I'm trying to create an API that servers a mobile application. I'm using Laravel 5.3 with Passport.

The flow itself is like this. The mobile app will provide the API a facebook access token which will be used to grab some information about the user(facebook id, name, profile picture and email). At that point the backend will insert, if it doesn't already exist, above information into the users table, basically creating a new user. Notice that nowhere does the backend login into facebook in anyway, as the access token is already granted by the mobile app.

After that what needs to happen is the backend will provide an access token to the mobile app that will be used to access other routes from the API itself. This should be done via Passport. As far as I can tell via Passport a new client needs to be created for each user, but I'm not looking for that since the mobile app is the only "client" that the API will have. The users created via facebook are actually users of the mobile app not the API itself. The schema for the oauth_clients is:

CREATE TABLE `oauth_clients` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `secret` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `redirect` text COLLATE utf8_unicode_ci NOT NULL,
  `personal_access_client` tinyint(1) NOT NULL,
  `password_client` tinyint(1) NOT NULL,
  `revoked` tinyint(1) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `oauth_clients_user_id_index` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

I didn't modify this in any way, it's the default schema.

Which makes no sense for my needs, I don't want a bunch of clients, I want just one client. The mobile app itself.

I of course could create a user just for the mobile app itself and the facebook users will be always assigned the mobile app user_id in the oauth_clients table, but that just seems wrong.

  • 写回答

2条回答 默认 最新

  • douhan1860 2016-11-03 20:44
    关注

    The problem with Laravel 5.3 passport is that unlike previous OAuth 2.0 Server for Laravel library offered by lucadegasperi, it has no API to make clients directly . So as if now the client can only be made through the front-end. FYI we wanted to use laravel passport solely for our mobile app so while creating and registering user we would have only EMAIL & Password and in some cases only Facebook UserID.

    1. in the oauth_clients convert the id field into a normal field i.e. remove it as being primary key and make the data type as varchar so that we can store email address as client_ids as they are also unique for your system. Incase of Facebook login we store Facebook user IDs here in this column which again will be unique for each our client. Also for other tables like: oauth_access_tokens, oauth_auth_codes & oauth_personal_access_clients change client_id to VARCHAR(255) so that it can store email addresses or Facebook User IDs.

    2. Now go to your models and create a model for oauth_clients table so that you can create client pragmatically from the code while creating users.

      <?php
      namespace App;
      
      
      use Illuminate\Database\Eloquent\Model;
      
      class oAuthClient extends Model
      {
      
      protected $table = 'oauth_clients';
      
      }
      
    3. Then you in your api.php route file add the following route:

      Route::post('/register-user', function () {
      
      $email= \Illuminate\Support\Facades\Input::get('email');
      $password=\Illuminate\Support\Facades\Input::get('password');
      
      $user = new \App\User(array(
      'name' =>\Illuminate\Support\Facades\Input::get('name'),
      'email' => \Illuminate\Support\Facades\Input::get('email'),
      'password' => bcrypt(\Illuminate\Support\Facades\Input::get('password')),
      ));
      $user->save();
      
      $oauth_client=new \App\oAuthClient();
      $oauth_client->user_id=$user->id;
      $oauth_client->id=$email;
      $oauth_client->name=$user->name;
      $oauth_client->secret=base64_encode(hash_hmac('sha256',$password, 'secret', true));
      $oauth_client->password_client=1;
      $oauth_client->personal_access_client=0;
      $oauth_client->redirect='';
      $oauth_client->revoked=0;
      $oauth_client->save();
      
      return [
      'message' => 'user successfully created.'
      ];
      });
      

    In the above code snippet you have to note that to generate the oauth_client secret you have to use some strong formula of encryption that you feel comfortable using it with your application. Also use the same technique to generate the secret key on your mobile app for the respective client/user.

    1. Now you can use the standard POST API offered by laravel passport to request access token through password grant using "oauth/token" using the following paramters:

      grant_type : 'password'
      client_id  : '<email with which the user is registered>'
      client_secret : '<generate the client secret from the mobile app>'
      username : '<email with which the user is registered>'
      password : '<password entered by the user>'
      scope : '<leave empty as default>'
      
    2. The above will give you a response, if everything is correct, similar to :

      {
        "token_type": "Bearer",
        "expires_in": 3155673600,
        "access_token":         "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3In0.eyJhdWQiOiJzaHVqYWhtQGdtYWlsLmNvbSIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3IiwiaWF0IjoxNDc4MTQ1NjMyLCJuYmYiOjE0NzgxNDU2MzIsImV4cCI6NDYzMzgxOTIzMiwic3ViIjoiMSIsInNjb3BlcyI6W119.dj3g9b2AdPCK-im5uab-01SP71S7AR96R0FQTKKoaZV7M5ID1pSXDlmZw96o5Bd_Xsy0nUqFsPNRQsLvYaOuHZsP8v9mOVirBXLIBvPcBc6lDRdNXvRidNqeh4JHhJu9a5VzNlJPm3joBYSco4wYzNHs2BPSxXuuD3o63nKRHhuUHB-HwjVxj2GDwzEYXdZmf2ZXOGRJ99DlWGDvWx8xQgMQtd1E9Xk_Rs6Iu8tycjBpKBaC24AKxMI6T8DpelnFmUbMcz-pRsgCWCF_hxv6FpXav3jr1CLhhT58_udBvXjQAXEbtHeB7W_oaMcaqezHdAeOWDcnqREZHsnXHtKt0JpymcTWBkS2cg7sJzy6P9mOGgQ8B4gb8wt44_kHTeWnokk4yPFRZojkHLVZb8YL6hZxLlzgV1jCHUxXoHNe1VKlHArdlV8LAts9pqARZkyBRfwQ8oiTL-2m16FQ_qGg-9vI0Suv7d6_W126afI3LxqDBi8AyqpQzZX1FWmuJLV0QiNM0nzTyokzz7w1ilJP2PxIeUzMRlVaJyA395zq2HjbFEenCkd7bAmTGrgEkyWM6XEq1P7qIC_Ne_pLNAV6DLXUpg9bUWEHhHPXIDYKHS-c3N9fPDt8UVvGI8n0rPMieTN92NsYZ_6OqLNpcm6TrhMNZ9eg5EC0IPySrrv62jE",
        "refresh_token": "BbwRuDnVfm7tRQk7qSYByFbQKK+shYPDinYA9+q5c/ovIE1xETyWitvq6PU8AHnI5FWb06Nl2BVoBwCHCUmFaeRXQQgYY/i5vIDEQ/TJYFLVPRHDc7CKILF0kMakWKDk7wJdl5J6k5mN38th4pAAZOubiRoZ+2npLC7OSZd5Mq8LCBayzqtyy/QA5MY9ywCgb1PErzrGQhzB3mNhKj7U51ZnYT3nS5nCH7iJkCjaKvd/Hwsx2M6pXnpY45xlDVeTOjZxxaOF/e0+VT2FP2+TZMDRfrSMLBEkpbyX0M/VxunriRJPXTUvl3PW0sVOEa3J7+fbce0XWAKz7PNs3+hcdzD2Av2VHYF7/bJwcDCO77ky0G4JlHjqC0HnnGP2UWI5qR+tCSBga7+M1P3ESjcTCV6G6H+7f8SOSv9FECcJ8J5WUrU+EHrZ95bDtPc9scE4P3OEQaYchlC9GHk2ZoGo5oMJI6YACuRfbGQJNBjdjxvLIrAMrB6DNGDMbH6UZodkpZgQjGVuoCWgFEfLqegHbp34CjwL5ZFJGohV+E87KxedXE6aEseywyjmGLGZwAekjsjNwuxqD2QMb05sg9VkiUPMsvn45K9iCLS5clEKOTwkd+JuWw2IU80pA24aXN64RvOJX5VKMN6CPluJVLdjHeFL55SB7nlDjp15WhoMU1A="
      }
      

    Hope it helps you! Cheers.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改