概要

原来有个网站,存在完善的账号管理,现在要增加一个网站,希望能使用统一的账号管理。

理想的方案是增加一个OAuth2服务,两个网站分别接入这个服务。但是由于特别的原因,旧网站只能进行微小的发动,于是要求这个 OAuth2 要能够支持自定义流程以旧网站的顺利接入而且不需要多少的变化。最终选择了使用 AWS Cognito 服务

参考文档:使用 Lambda 触发器自定义用户池工作流

- 阅读剩余部分 -

react-schema-form

  1. Design with no theme, Has Core Package and Bootstrap package ↑↑
  2. The size of the file after compile is small ↑
  3. Not a stable package ↓
  4. Easy to implement ↑
  5. If field is empty, props in form-data is deleted. ↑
  6. When field is hide, props in form-data is visible. ↓
  7. Custom template is easy ↑↑
  8. Some default template break the style of custom template ↓

React-jsons-form

  1. Design with material-ui ↓
  2. The size of the file after compile is large↓
  3. Stable package ↑
  4. Easy to implement ↑
  5. If field is empty, props in form-data is an empty string ↓
  6. When field is hide, props in form-data is visible ↓
  7. Custom Template is easy ↑
  8. but hard to overwrite default template ↓

ResourceCollection 是用于处理 返回值为json的时候定义返回的集合的格式,集合内的单个元素可以使用 Illuminate\Http\Resources\Json\JsonResource 定义,或者直接在toArray中重新定义。

use App\User;
use App\Http\Resources\User as UserResource;

Route::get('/user', function () {
    return UserResource::collection(User::all());
});

// 如果定义了Collection 

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}
// 新的写法
use App\User;
use App\Http\Resources\UserCollection;

Route::get('/users', function () {
    return new UserCollection(User::all());
});

当前使用版本 v1.6.3

belongsTo 关系使用问题

  • 外键名必须填写,否则不能正确的保存。
  • 外键需要允许为空(nullable)否则会报错(已经提交issue截止目前未修复)

    // tables 
          Schema::create('users', function (Blueprint $table) {
              $table->uuid('id');
              $table->string('email', 64)->unique();
              $table->boolean('revoked')->default(0);
              $table->dateTime('email_verified_at')->nullable();
              $table->string('password');
              $table->rememberToken();
              $table->timestamps();
          });
    
    
          Schema::create('profiles', function (Blueprint $table) {
              $table->increments('id');
              $table->uuid('user_id')->nullable()->index();  // 目前需要为 nullable, 这个bug目前为止还没有修复
              $table->string('name');
              $table->string('description')->nullable();
              $table->timestamps();
          });
    class Teacher extends Model
    {
      protected $guarded=[];
      //
      public function user() {
          return $this->belongsTo(User::class, 'user_id', 'id');  // 这里必须填写,虽然Laravel 虽然在Laravel 中默认就是这些值,但是Laravel-Admin 没办法获取到默认的字段名
      }
    }
    // Model
    
    class User extends Authenticatable
    {
      use Notifiable;
    
      public $incrementing=false;
      /**
       * The attributes that should be hidden for arrays.
       *
       * @var array
       */
      protected $hidden = [
          'password', 'remember_token',
      ];
    
      public function profile() {
          return $this->hasOne(Profile::class);
      }
    }
    
    // Form
    
          $form = new Form(new Profile);
    
          $form->text('name', '姓名')->rules('required');
          $form->password('user.email', '密码')->rules('required');
          $form->password('user.password', '密码')->rules('required');
          $form->textarea('description', '描述');
    
    //
    

    haseMany 关系

  • 主键必须为自动生成,否则不能正确的保存从表
    tables

    CREATE TABLE `main` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `sub` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, // 非自动生成主键不能正确的保存
    `key` int(10) varchar(100) NOT NULL,
    `main_id` int(10) unsigned NOT NULL,
    `value` varchar(255) NOT NULL,
    PRIMARY KEY (`id`),
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    Models

    class Main extends Model
    {
      public $timestamps = false;
      public function subs()
      {
          return $this->hasMany(Sub::class, 'main_id');  // main_id 必须填写,虽然 Laravel 单独使用的时候可以不用写
      }
    }
    
    class Sub extends Model
    {
      public $timestamps = false;
      // public $incrementing = false; // 如果没有自动生成的主键而是 key 做为主键的话,会导表单中Sub保存失败,key 为空
      // public $primaryKey = 'key';
      protected $fillable = ['key', 'value'];
    
      public function main()
      {
          return $this->belongsTo(Main::class, 'main_id'); //同上
      }
    }
    

    Form

    
          $form = new Form(new Main);
          $form->text('name', '名称');
          $form->hasMany('subs','从表', function (Form\NestedForm $form) {
              $form->text('key');
              $form->text('value');
          });
          return $form;
    

    结论

Laravel-admin 完全不适合使用于生产环境,复杂的关系还没有完善

What can do

Good at all simple business, not dependent on the server, can be used with API-Gateway.
Only need sample functions.

What to do

first of all, we need a AWS account.
launch AWS Console

Create a Function

goto Lambda->Dashbord click the button Create function
enter a name for this function
create a new role for this function.
select Runtime as Nodejs 8.10 (this only nodejs code)
see: Lamda Functions
see: Using an IAM Role

hander is important

The module-name.export value in your function. For example, "index.handler" would call exports.handler in index.js.