参考链接:An Introduction to Laravel Authorization Gates

本文使用 Laravel 的 Gate 授权方式 实现一个基于用户角色的博客发布系统。

在系统包含两个用户角色(作者编辑),它们对应的角色权限如下:

  1. 作者能创建博客
  2. 作者能更新自己的博客
  3. 作者能发布/不发布自己的博客
  4. 作者能删除自己的博客
  5. 编辑能更新所有博客
  6. 编辑能发布/不发布所有博客
  7. 编辑能删除所有博客

创建项目

  1. laravel new blog
  2. > php artisan -V
  3. Laravel Framework 5.4.21

或者使用 composer create-project

  1. composer create-project --prefer-dist laravel/laravel blog

配置数据库连接

修改 .env 文件中的数据库连接信息。

  1. ...
  2. APP_URL=http://localhost
  3. ...
  4. DB_CONNECTION=mysql
  5. DB_HOST=127.0.0.1
  6. DB_PORT=3306
  7. DB_DATABASE=dbname
  8. DB_USERNAME=dbuser
  9. DB_PASSWORD=yoursecretdbuserpassword
  10. ...

数据库部分

创建 Post Model、Post 迁移文件和 Post 控制器。

  1. > php artisan make:model Post -m -c
  2. Model created successfully.
  3. Created Migration: 2017_05_07_083335_create_posts_table
  4. Controller created successfully.

打开迁移文件,补充 up 方法。

  1. Schema::create('posts', function (Blueprint $table) {
  2. $table->increments('id');
  3. $table->string('title');
  4. $table->string('slug')->unique();
  5. $table->text('body');
  6. $table->boolean('published')->default(false);
  7. $table->unsignedInteger('user_id');
  8. $table->timestamps();
  9. $table->foreign('user_id')->references('id')->on('users');
  10. });

添加 roles 表和关系表 user_roles

  1. roles

创建 Role Model 和 Role 迁移文件

  1. > php artisan make:model Role -m
  2. Model created successfully.
  3. Created Migration: 2017_05_07_083537_create_roles_table

打开迁移文件,补充 up 方法。

  1. Schema::create('roles', function (Blueprint $table) {
  2. $table->increments('id');
  3. $table->string('name');
  4. $table->string('slug')->unique();
  5. $table->jsonb('permissions'); // jsonb deletes duplicates
  6. $table->timestamps();
  7. });
  1. user_roles

创建迁移文件

  1. php artisan make:migration create_user_roles_table --create=user_roles

补充 up 方法

  1. public function up()
  2. {
  3. Schema::create('user_roles', function (Blueprint $table) {
  4. $table->unsignedInteger('user_id');
  5. $table->unsignedInteger('role_id');
  6. $table->timestamps();
  7. $table->unique(['user_id','role_id']);
  8. $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
  9. $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
  10. });
  11. }
  12. public function down()
  13. {
  14. Schema::dropIfExists('user_roles');
  15. }

种子类

创建 RolesTableSeeder

  1. php artisan make:seeder RolesTableSeeder

补充 run 方法。

  1. use App\Role;
  2. class RolesTableSeeder extends Seeder
  3. {
  4. public function run()
  5. {
  6. $author = Role::create([
  7. 'name' => '作家',
  8. 'slug' => 'author',
  9. 'permissions' => [
  10. 'create-post' => true,
  11. ]
  12. ]);
  13. $editor = Role::create([
  14. 'name' => '编辑',
  15. 'slug' => 'editor',
  16. 'permissions' => [
  17. 'update-post' => true,
  18. 'publish-post' => true,
  19. 'delete-post' => true,
  20. ]
  21. ]);
  22. }
  23. }

DatabaseSeeder 中注册 RolesTableSeeder

  1. $this->call(RolesTableSeeder::class);

UserRole Model

添加 Role Model 的内容。

  1. class Role extends Model
  2. {
  3. protected $fillable = [
  4. 'name', 'slug', 'permissions',
  5. ];
  6. protected $casts = [
  7. 'permissions' => 'array',
  8. ];
  9. public function users()
  10. {
  11. return $this->belongsToMany(User::class, 'user_roles', 'role_id', 'user_id');
  12. }
  13. public function hasAccess($permission)
  14. {
  15. return $this->hasPermission($permission);
  16. }
  17. private function hasPermission($permission)
  18. {
  19. return isset($this->permissions[$permission]) ? $this->permissions[$permission] : false;
  20. }
  21. }

添加 User Model 的内容。

  1. class User extends Authenticatable
  2. {
  3. use Notifiable;
  4. protected $fillable = [
  5. 'name', 'email', 'password',
  6. ];
  7. protected $hidden = [
  8. 'password', 'remember_token',
  9. ];
  10. public function roles()
  11. {
  12. return $this->belongsToMany(Role::class, 'user_roles', 'user_id', 'role_id');
  13. }
  14. /**
  15. * Checks if User has access to $permission.
  16. */
  17. public function hasAccess($permission)
  18. {
  19. // check if the permission is available in any role
  20. foreach ($this->roles as $role) {
  21. if($role->hasAccess($permission)) {
  22. return true;
  23. }
  24. }
  25. return false;
  26. }
  27. /**
  28. * Checks if the user belongs to role.
  29. */
  30. public function inRole($roleSlug)
  31. {
  32. return $this->roles()->where('slug', $roleSlug)->count() == 1;
  33. }
  34. }

执行迁移和数据注入

  1. php artisan migrate --seed

认证系统

  1. > php artisan make:auth
  2. Authentication scaffolding generated successfully.

注册

Controllers/Auth/RegisterController.php 创建 showRegistrationForm 方法(覆盖掉在 RegistersUsers trait 中定义)。

  1. Use App/Role;
  2. ...
  3. public function showRegistrationForm()
  4. {
  5. $roles = Role::orderBy('name')->pluck('name', 'id');
  6. return view('auth.register', compact('roles'));
  7. }

编辑 resources/views/auth/register.blade.php,添加角色选择项。

  1. ...
  2. <div class="form-group{{ $errors->has('role') ? ' has-error' : '' }}">
  3. <label for="role" class="col-md-4 control-label">User role</label>
  4. <div class="col-md-6">
  5. <select id="role" class="form-control" name="role" required>
  6. @foreach($roles as $id => $role)
  7. <option value="{{ $id }}">{{ $role }}</option>
  8. @endforeach
  9. </select>
  10. @if ($errors->has('role'))
  11. <span class="help-block">
  12. <strong>{{ $errors->first('role') }}</strong>
  13. </span>
  14. @endif
  15. </div>
  16. </div>
  17. ...

更新 RegisterController 中的 validator 方法。

  1. ...
  2. protected function validator(array $data)
  3. {
  4. return Validator::make($data, [
  5. 'name' => 'required|max:255',
  6. 'email' => 'required|email|max:255|unique:users',
  7. 'password' => 'required|min:6|confirmed',
  8. 'role' => 'required|exists:roles,id', // validating role
  9. ]);
  10. }
  11. ...

修改 create 方法,加入存储用户角色的业务逻辑。

  1. ...
  2. protected function create(array $data)
  3. {
  4. $user = User::create([
  5. 'name' => $data['name'],
  6. 'email' => $data['email'],
  7. 'password' => bcrypt($data['password']),
  8. ]);
  9. $user->roles()->attach($data['role']);
  10. return $user;
  11. }
  12. ...

运行项目

浏览器地址栏输入: http://localhost/blog/public/ 。看到欢迎页面、注册用户。

定义策略

修改 app/Providers/AuthServiceProvider.php 文件。

  1. use App\Post;
  2. ...
  3. public function boot()
  4. {
  5. $this->registerPolicies();
  6. $this->registerPostPolicies();
  7. }
  8. public function registerPostPolicies()
  9. {
  10. Gate::define('create-post', function ($user) {
  11. return $user->hasAccess('create-post');
  12. });
  13. Gate::define('update-post', function ($user, Post $post) {
  14. return $user->hasAccess('update-post') or $user->id == $post->user_id;
  15. });
  16. Gate::define('publish-post', function ($user, Post $post) {
  17. return $user->hasAccess('publish-post') or $user->id == $post->user_id;;
  18. });
  19. Gate::define('delete-post', function ($user, Post $post) {
  20. return $user->hasAccess('delete-post') or $user->id == $post->user_id;
  21. });
  22. Gate::define('see-all-drafts', function ($user) {
  23. return $user->inRole('editor');
  24. });
  25. }

定义路由

修改 routes/web.php

  1. Route::get('/posts', 'PostController@index')->name('list_posts');
  2. Route::group(['prefix' => 'posts'], function () {
  3. Route::get('/drafts', 'PostController@drafts')
  4. ->name('list_drafts')
  5. ->middleware('auth');
  6. Route::get('/show/{id}', 'PostController@show')
  7. ->name('show_post');
  8. Route::get('/create', 'PostController@create')
  9. ->name('create_post')
  10. ->middleware('can:create-post');
  11. Route::post('/create', 'PostController@store')
  12. ->name('store_post')
  13. ->middleware('can:create-post');
  14. Route::get('/edit/{post}', 'PostController@edit')
  15. ->name('edit_post')
  16. ->middleware('can:update-post,post');
  17. Route::post('/edit/{post}', 'PostController@update')
  18. ->name('update_post')
  19. ->middleware('can:update-post,post');
  20. Route::post('/delete/{post}', 'PostController@destory')
  21. ->name('delete_post')
  22. ->middleware('can:delete-post,post');
  23. // using get to simplify
  24. Route::get('/publish/{post}', 'PostController@publish')
  25. ->name('publish_post,post')
  26. ->middleware('can:publish-post');
  27. Route::get('/unpublish/{post}', 'PostController@unpublish')
  28. ->name('unpublish_post')
  29. ->middleware('can:publish-post,post');
  30. });

博客

Post Model

  1. ...
  2. class Post extends Model
  3. {
  4. protected $fillable = [
  5. 'title', 'slug', 'body', 'user_id',
  6. ];
  7. public function owner()
  8. {
  9. return $this->belongsTo(User::class);
  10. }
  11. public function scopePublished($query)
  12. {
  13. return $query->where('published', true);
  14. }
  15. public function scopeUnpublished($query)
  16. {
  17. return $query->where('published', false);
  18. }
  19. }

PostController

博客列表

  1. use App\Post;
  2. ...
  3. public function index()
  4. {
  5. $posts = Post::published()->latest()->paginate();
  6. return view('posts.index', compact('posts'));
  7. }
  8. ...

创建 resources/views/posts/index.blade.php

  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="container">
  4. <div class="row">
  5. <div class="col-md-8 col-md-offset-2">
  6. <div class="panel panel-default">
  7. <div class="panel-heading">
  8. Posts
  9. @can('create-post')
  10. <a class="pull-right btn btn-sm btn-primary" href="{{ route('create_post') }}">New</a>
  11. @endcan
  12. </div>
  13. <div class="panel-body">
  14. <div class="row">
  15. @foreach($posts as $post)
  16. <div class="col-sm-6 col-md-4">
  17. <div class="thumbnail">
  18. <div class="caption">
  19. <h3><a href="{{ route('show_post', ['id' => $post->id]) }}">{{ $post->title }}</a></h3>
  20. <p>{{ str_limit($post->body, 50) }}</p>
  21. @can('update-post', $post)
  22. <p>
  23. <a href="{{ route('edit_post', ['id' => $post->id]) }}" class="btn btn-sm btn-default" role="button">Edit</a>
  24. </p>
  25. @endcan
  26. </div>
  27. </div>
  28. </div>
  29. @endforeach
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. </div>
  36. @endsection

创建博客

  1. ...
  2. public function create()
  3. {
  4. return view('posts.create');
  5. }
  6. ...

创建 posts\create.blade.php

  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="container">
  4. <div class="row">
  5. <div class="col-md-8 col-md-offset-2">
  6. <div class="panel panel-default">
  7. <div class="panel-heading">New Post</div>
  8. <div class="panel-body">
  9. <form class="form-horizontal" role="form" method="POST" action="{{ route('store_post') }}">
  10. {{ csrf_field() }}
  11. <div class="form-group{{ $errors->has('title') ? ' has-error' : '' }}">
  12. <label for="title" class="col-md-2 control-label">Title</label>
  13. <div class="col-md-9">
  14. <input id="title" type="text" class="form-control" name="title" value="{{ old('title') }}" required autofocus>
  15. @if ($errors->has('title'))
  16. <span class="help-block">
  17. <strong>{{ $errors->first('title') }}</strong>
  18. </span>
  19. @endif
  20. </div>
  21. </div>
  22. <div class="form-group{{ $errors->has('body') ? ' has-error' : '' }}">
  23. <label for="body" class="col-md-2 control-label">Body</label>
  24. <div class="col-md-9">
  25. <textarea name="body" id="body" cols="30" rows="10" class="form-control" required>{{ old('body') }}</textarea>
  26. @if ($errors->has('body'))
  27. <span class="help-block">
  28. <strong>{{ $errors->first('body') }}</strong>
  29. </span>
  30. @endif
  31. </div>
  32. </div>
  33. <div class="form-group">
  34. <div class="col-md-6 col-md-offset-2">
  35. <button type="submit" class="btn btn-primary">
  36. Create
  37. </button>
  38. <a href="{{ route('list_posts') }}" class="btn btn-primary">
  39. Cancel
  40. </a>
  41. </div>
  42. </div>
  43. </form>
  44. </div>
  45. </div>
  46. </div>
  47. </div>
  48. </div>
  49. @endsection

保存博客

  1. use Auth;
  2. use App\Http\Requests\StorePost as StorePostRequest;
  3. ...
  4. public function store(StorePostRequest $request)
  5. {
  6. $data = $request->only('title', 'body');
  7. $data['slug'] = str_slug($data['title']);
  8. $data['user_id'] = Auth::user()->id;
  9. $post = Post::create($data);
  10. return redirect()->route('edit_post', ['id' => $post->id]);
  11. }
  12. ...

创建处理存储博客时使用的请求类 StorePostRequest

  1. php artisan make:request StorePostRequest

编辑 app/Http/Requests/StorePost.php

  1. public function authorize()
  2. {
  3. return true; // gate will be responsible for access
  4. }
  5. public function rules()
  6. {
  7. return [
  8. 'title' => 'required|unique:posts',
  9. 'body' => 'required',
  10. ];
  11. }

博客草稿列表

  1. use Gate;
  2. ...
  3. public function drafts()
  4. {
  5. $postsQuery = Post::unpublished();
  6. if(Gate::denies('see-all-drafts')) {
  7. $postsQuery = $postsQuery->where('user_id', Auth::user()->id);
  8. }
  9. $posts = $postsQuery->paginate();
  10. return view('posts.drafts', compact('posts'));
  11. }
  12. ...

创建 posts/drafts.blade.php

  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="container">
  4. <div class="row">
  5. <div class="col-md-8 col-md-offset-2">
  6. <div class="panel panel-default">
  7. <div class="panel-heading">
  8. Drafts <a class="btn btn-sm btn-default pull-right" href="{{ route('list_posts') }}">Return</a>
  9. </div>
  10. <div class="panel-body">
  11. <div class="row">
  12. @foreach($posts as $post)
  13. <div class="col-sm-6 col-md-4">
  14. <div class="thumbnail">
  15. <div class="caption">
  16. <h3><a href="{{ route('show_post', ['id' => $post->id]) }}">{{ $post->title }}</a></h3>
  17. <p>{{ str_limit($post->body, 50) }}</p>
  18. <p>
  19. @can('publish-post', $post)
  20. <a href="{{ route('publish_post', ['id' => $post->id]) }}" class="btn btn-default" role="button">Publish</a>
  21. @endcan
  22. <a href="{{ route('edit_post', ['id' => $post->id]) }}" class="btn btn-default" role="button">Edit</a>
  23. </p>
  24. </div>
  25. </div>
  26. </div>
  27. @endforeach
  28. <div class="col-sm-12 col-md-12">
  29. {{ $posts->links() }}
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. </div>
  36. </div>
  37. @endsection

修改 layouts/app.blade.php,添加“草稿”菜单。

  1. ...
  2. <ul class="dropdown-menu" role="menu">
  3. <li>
  4. <a href="{{ route('list_drafts') }}">Drafts</a>
  5. ...

编辑博客

添加编辑博客的方法 update

  1. use App\Http\Requests\UpdatePostRequest as UpdatePostRequest;
  2. ...
  3. public function edit(Post $post)
  4. {
  5. return view('posts.edit', compact('post'));
  6. }
  7. public function update(Post $post, UpdatePostRequest $request)
  8. {
  9. $data = $request->only('title', 'body');
  10. $data['slug'] = str_slug($data['title']);
  11. $post->fill($data)->save();
  12. return back();
  13. }

创建处理更新博客时使用的请求类 UpdatePostRequest

  1. php artisan make:request UpdatePostRequest

编辑 app/Http/Requests/UpdatePostRequest.php

  1. use Illuminate\Validation\Rule;
  2. ...
  3. public function authorize()
  4. {
  5. return true;
  6. }
  7. public function rules()
  8. {
  9. $id = $this->route('post')->id;
  10. return [
  11. 'title' => [
  12. 'required',
  13. Rule::unique('posts')->where('id', '<>', $id),
  14. ],
  15. 'body' => 'required',
  16. ];
  17. }

创建视图 posts/edit.blade.php

  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="container">
  4. <div class="row">
  5. <div class="col-md-8 col-md-offset-2">
  6. <div class="panel panel-default">
  7. <div class="panel-heading">Update Post</div>
  8. <div class="panel-body">
  9. <form class="form-horizontal" role="form" method="POST" action="{{ route('update_post', ['post' => $post->id]) }}">
  10. {{ csrf_field() }}
  11. <div class="form-group{{ $errors->has('title') ? ' has-error' : '' }}">
  12. <label for="title" class="col-md-2 control-label">Title</label>
  13. <div class="col-md-9">
  14. <input id="title" type="text" class="form-control" name="title" value="{{ old('title', $post->title) }}" required autofocus>
  15. @if ($errors->has('title'))
  16. <span class="help-block">
  17. <strong>{{ $errors->first('title') }}</strong>
  18. </span>
  19. @endif
  20. </div>
  21. </div>
  22. <div class="form-group{{ $errors->has('body') ? ' has-error' : '' }}">
  23. <label for="body" class="col-md-2 control-label">Body</label>
  24. <div class="col-md-9">
  25. <textarea name="body" id="body" cols="30" rows="10" class="form-control" required>{{ old('body', $post->body) }}</textarea>
  26. @if ($errors->has('body'))
  27. <span class="help-block">
  28. <strong>{{ $errors->first('body') }}</strong>
  29. </span>
  30. @endif
  31. </div>
  32. </div>
  33. <div class="form-group">
  34. <div class="col-md-6 col-md-offset-2">
  35. <button type="submit" class="btn btn-primary">
  36. Update
  37. </button>
  38. @can('publish-post', $post)
  39. @if (!$post->published)
  40. <a href="{{ route('publish_post', ['post' => $post->id]) }}" class="btn btn-primary">
  41. Publish
  42. </a>
  43. @else
  44. <a href="{{ route('unpublish_post', ['post' => $post->id]) }}" class="btn btn-primary">
  45. Unpublish
  46. </a>
  47. @endif
  48. @endcan
  49. <a href="{{ route('list_posts') }}" class="btn btn-primary">
  50. Cancel
  51. </a>
  52. </div>
  53. </div>
  54. </form>
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. </div>
  60. @endsection

发布草稿/不发布草稿

PostController 添加方法 publishunpublish

  1. ...
  2. public function publish(Post $post)
  3. {
  4. $post->published = true;
  5. $post->save();
  6. return redirect()->route('show_post', ['post' => $post->id]);
  7. }
  8. public function unpublish(Post $post)
  9. {
  10. $post->published = false;
  11. $post->save();
  12. return back();
  13. }
  14. ...

展示博客

  1. public function show(Post $post)
  2. {
  3. $post = Post::findOrFail($id);
  4. if ($post->published || $post->user_id == Auth::user()->id) {
  5. return view('posts.show', compact('post'));
  6. }
  7. abort(403, 'Unauthorized.');
  8. }

创建 posts/show.blade.php

  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="container">
  4. <div class="row">
  5. <div class="col-md-8 col-md-offset-2">
  6. <div class="panel panel-default">
  7. <div class="panel-heading">
  8. {{ $post->title }}
  9. <a class="btn btn-sm btn-default pull-right" href="{{ route('list_posts') }}">Return</a>
  10. </div>
  11. <div class="panel-body">
  12. {{ $post->body }}
  13. </div>
  14. </div>
  15. </div>
  16. </div>
  17. </div>
  18. @endsection

删除博客

修改 PostController,添加 destory 方法。

  1. public function destory(Post $post)
  2. {
  3. $post->delete();
  4. return redirect()->route('list_post');;
  5. }

修改 posts/edit.blade.php,添加删除按钮。

  1. ...
  2. <div class="panel-heading">Update Post
  3. @can('delete-post', $post)
  4. <a class="pull-right btn btn-sm btn-danger" href="{{ route('delete_post', ['id' => $post->id]) }}"
  5. onclick="if(confirm('确定删除吗?') === false) { return false; } else {
  6. event.preventDefault(); document.getElementById('delete-post-form').submit();}">
  7. 删除
  8. </a>
  9. <form id="delete-post-form" action="{{ route('delete_post', ['post' => $post->id]) }}" method="POST" style="display: none;">
  10. {{ csrf_field() }}
  11. </form>
  12. @endcan
  13. </div>
  14. ...

404 & 403

resources/views 下新建 errors 目录,再在该目录下新建 404.blade.php403.blade.php 页面。

404

  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="container">
  4. <div class="row">
  5. <div class="col-md-8 col-md-offset-2">
  6. <div class="panel panel-default">
  7. <div class="panel-heading">404</div>
  8. <div class="panel-body">
  9. <h2>Not Found</h2>
  10. </div>
  11. </div>
  12. </div>
  13. </div>
  14. </div>
  15. @endsection

403

  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="container">
  4. <div class="row">
  5. <div class="col-md-8 col-md-offset-2">
  6. <div class="panel panel-default">
  7. <div class="panel-heading">403</div>
  8. <div class="panel-body">
  9. <h2>This Action is Unauthorized!</h2>
  10. </div>
  11. </div>
  12. </div>
  13. </div>
  14. </div>
  15. @endsection

使用 Markdown

这里要安装依赖包 erusev/parsedown,使用它将 Markdown 文本装换为 HTML。

  1. composer require erusev/parsedown

修改 posts/show.blade.php

  1. <div class="panel-body">
  2. {!! Parsedown::instance()->text($post->body) !!}
  3. </div>

此刻,你就可以使用 Markdown 写博客了。

tags: Laravel 项目

Laravel Gate 授权方式的使用指南的更多相关文章

  1. [转]OAuth 2.0 - Authorization Code授权方式详解

    本文转自:http://www.cnblogs.com/highend/archive/2012/07/06/oautn2_authorization_code.html I:OAuth 2.0 开发 ...

  2. spring-oauth-server实践:授权方式四:client_credentials 模式的refresh_token?

    spring-oauth-server入门(1-13)授权方式四:client_credentials 模式的refresh_token? 有效期内的反复申请access_token获取失效日期不变! ...

  3. spring-oauth-server实践:授权方式四:client_credentials 模式下有效期内重复申请 access_token ?

    spring-oauth-server入门(1-12)授权方式四:client_credentials 模式下有效期内重复申请 access_token ? 一.失效重建邏輯 二.如果沒有失效,不会重 ...

  4. spring-oauth-server实践:使用授权方式四:client_credentials 模式的客户端和服务端交互

    spring-oauth-server入门(1-11)使用授权方式四:client_credentials 模式的客戶端 一.客户端逻辑 1.界面入口(credentials_access_token ...

  5. spring-oauth-server实践:使用授权方式四:client_credentials 模式下access_token做业务!!!

    spring-oauth-server入门(1-10)使用授权方式四:client_credentials 模式下access_token做业务!!! 准备工作 授权方式四::客户端方式: 服务网关地 ...

  6. spring-oauth-server实践:授权方式1、2、3和授权方式4的token对象.authorities产生方式比较

    授权方式1.2.3和授权方式4的token对象.authorities产生方式不同, 前者使用user_privillege构建, 后者直接使用oauth_client_details.authort ...

  7. OAuth2.0学习(1-7)授权方式4-客户端模式(Client Credentials Grant)

    授权方式4-客户端模式(Client Credentials Grant) 客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提 ...

  8. OAuth2.0学习(1-6)授权方式3-密码模式(Resource Owner Password Credentials Grant)

    授权方式3-密码模式(Resource Owner Password Credentials Grant) 密码模式(Resource Owner Password Credentials Grant ...

  9. OAuth2.0学习(1-5)授权方式2-简化模式(implicit grant type)

    授权方式2-简化模式(implicit grant type) 简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授 ...

随机推荐

  1. 使用DeflateStream压缩与解压

    具体可以了解下:http://msdn.microsoft.com/zh-cn/library/system.io.compression.deflatestream(v=vs.110).aspx / ...

  2. Linux C程序操作Mysql 调用PHP采集淘宝商品

    还是继续这个项目. 在上一篇Linux下利用Shell使PHP并发采集淘宝产品中,采用shell将对PHP的调用推到后台执行,模拟多线程. 此方法有一致命缺点,只能人工预判每个程序执行时间.如果判断时 ...

  3. selenium - 截取页面图片和截取某个元素的图

    1.截取页面图片并保存 在测试过程中,是有必要截图,特别是遇到错误的时候进行截图. # coding:utf-8 from time import sleep from PIL import Imag ...

  4. 转: 使用Jmeter创建ActiveMQ JMS POINT TO POINT请求,环境搭建、请求创建、插件安装、监听服务器资源等

    转自:http://www.cnblogs.com/qianyiliushang/p/4348584.html 准备工作: 安装JDK,推荐使用1.7以上版本,并设置JAVA_HOME 下载Jmete ...

  5. tomcat 并发配置优化

    修改tomcat/conf/server.xml配置文件. <Executor name="tomcatThreadPool" namePrefix="catali ...

  6. 整数a整数b

    namespace ConsoleApplication6{ class Program { static void Main(string[] args) { while (true) { Cons ...

  7. c#中{set;get;}使用逻辑

    (先把结论提前)下面两种定义私有变量配合公有变量的方法都没有意义,除非有特殊的逻辑需要在set或get中,其它情况都等效于 public GM_Arc Arc {set;get;} //不进行初始化, ...

  8. 在Centos7中安装elasticsearch5.5

    在Centos7中安装elasticsearch5.5 第一步:必须要有jre支持 elasticsearch是用Java实现的,跑elasticsearch必须要有jre支持,所以必须先安装jre ...

  9. CSS——优先级

    转自:http://www.planabc.net/2008/05/06/css_specificity/ CSS2.1 中规定了关于 CSS 规则 Specificity(特异性)的计算方式,用一个 ...

  10. c++builder Form重载WindowProc、WndProc 截获消息

    c++builder 重载WindowProc.WndProc 截获消息 方法一WindowProc void __fastcall  myWindowProc(Messages::TMessage ...