经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » PHP » 查看文章
单点登录 - API 认证系统 Passport(二)
来源:cnblogs  作者:SexyPhoenix  时间:2019/10/31 11:56:38  对本文有异议

安装

  1. composer require laravel/passport=~4.0

notes:
1)确保系统安装unzip、zip等命令。
2)composer 安装出现 Authentication required (packagist.phpcomposer.com) 问题,修改composer.json 中的源,repositories.packagist.url = https://packagist.laravel-china.org 。

注册服务提供者

在config/app.php的providers 数组中加入 Laravel\Passport\PassportServiceProvider::class

迁移数据库

  1. php artisan migrate //生成用于存储客户端和令牌的数据表

生成加密健

  1. php artisan passport:install

1、生成oauth-private.key(用于构建认证服务器),oauth-public.key(用于构建资源服务器)
2、oauth_clients数据库生成「个人访问」客户端和「密码授权]两条数据。

配置Passport(参考官方文档)

在Model中,我们需要增加 HasApiTokens class
在AuthServiceProvider中, 增加 "Passport::routes()"
在 auth.php中, 更改 api 认证方式为passport

申请客户端以及私人访问令牌 (两种方式)

1. 命令形式(不方便客户注册)
  1. php artisan passport:client

8

2. Passport Vue 组件
  1. php artisan vendor:publish --tag=passport-components //发布 Passport Vue,组件位于resources/assets/js/components下

//注册到resources/assets/js/app.js 文件,记得要放在new Vue上面

  1. Vue.component(
  2. 'passport-clients',
  3. require('./components/passport/Clients.vue')
  4. );
  5. Vue.component(
  6. 'passport-authorized-clients',
  7. require('./components/passport/AuthorizedClients.vue')
  8. );
  9. Vue.component(
  10. 'passport-personal-access-tokens',
  11. require('./components/passport/PersonalAccessTokens.vue')
  12. );

//编译前端资源

  1. npm install //此处报错,移步larravel Mix文档
  2. npm run dev

编译后资源放在public/js/app.js下

//组件放入应用模板(记得引入编译后的app.js)

  1. <passport-clients></passport-clients>
  2. <passport-authorized-clients></passport-authorized-clients>
  3. <passport-personal-access-tokens></passport-personal-access-tokens>

9
以上认证服务器都已经搭建完成

第三方应用实现登录

1. 申请客户端

10
回调地址 http://third.plat.goods/dew/sso

申请授权码和访问令牌

//获取授权码 code (第一次交互)

  1. $query = http_build_query(array(
  2. 'client_id' => 3,
  3. 'redirect_uri' => 'http://third.plat.goods/dew/sso', //地址必须为上面的回调地址
  4. 'response_type' => 'code', //固定值
  5. 'scope' => '',
  6. 'state' => urlencode('http://laravel.plat.goods/user') //可以放用户访问的地址。
  7. ));
  8. return redirect('http://laravel.plat.goods/oauth/authorize?'.$query); ///laravel.plat.goods为上面认证服务器

11
//获取访问令牌 access token 以及向资源服务器请求用户信息
授权后会重定向回调地址

  1. Route::get('/dew/sso', 'SSOController@callback'); //路由文件里添加
  2. php artisan make:controller SSOController //创建文件
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\User;
  4. use GuzzleHttp\Client;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Support\Facades\Log;
  7. class SSOController extends Controller
  8. {
  9. protected $http;
  10. public function __construct()
  11. {
  12. $this->http = new Client();
  13. }
  14. /**
  15. * 获取授权码后的回调URL
  16. * @param Request $request
  17. * @return \Illuminate\Http\RedirectResponse
  18. */
  19. public function callback(Request $request)
  20. {
  21. $token = $this->token($request); //第二次交互
  22. $login = $this->login($token);//第三次交互
  23. if($login){
  24. if($request_url = $request->input('state', null)){
  25. $request->session()->put('url.intended', urldecode($request_url));
  26. }
  27. return redirect()->intended(); //跳转到 http://laravel.plat.goods/user
  28. }else{
  29. return redirect()->to('http://laravel.plat.com/home/public/login'); //服务提供商网站必须登录
  30. }
  31. }
  32. /**
  33. * 获取access token
  34. * @param $request
  35. * @return array|mixed
  36. */
  37. protected function token($request)
  38. {
  39. $code = $request->code;
  40. if($code) {
  41. try {
  42. $response = $this->http->post('http://laravel.plat.goods/oauth/token', [
  43. 'form_params' => [
  44. 'grant_type' => 'authorization_code', //固定值
  45. 'client_id' => 3,
  46. 'client_secret' => 'UihXNHoSqohdtQ8Js6Av7AOyk3GBNB9rJziDPaWf',
  47. 'redirect_uri' => 'http://third.plat.goods/dew/sso',
  48. 'code' => $code,
  49. ],
  50. ]);
  51. $response_data = json_decode((string)$response->getBody(), true);
  52. return $response_data;
  53. } catch (\Exception $e) {
  54. Log::error('get token by code failed: '.$code.' - '.$e->getMessage().' - '.$e->getTraceAsString());
  55. return [];
  56. }
  57. }else{
  58. return [];
  59. }
  60. }
  61. /**
  62. * 通过token获取用户信息,并进行登录操作
  63. * @param $token
  64. * @return bool
  65. */
  66. protected function login($token)
  67. {
  68. if(empty($token)) return false;
  69. $access_token = $token['access_token'];
  70. try {
  71. // 资源服务器和认证服务器放在了一起,可以独立。
  72. $response = $this->http->request('GET', 'http://laravel.plat.goods/api/user', [
  73. 'headers' => [
  74. 'Accept' => 'application/json',
  75. 'Authorization' => $token['token_type'] . ' ' . $access_token,
  76. ]
  77. ]);
  78. $users_body = $response->getBody();
  79. $data = json_decode($users_body, true);
  80. if($data) {
  81. $user = new User($data);
  82. //because of employee_id is guarded
  83. $user->setAttribute($user->getKeyName(), $data['employee_id']);
  84. //login user in my system
  85. auth()->login($user, false);
  86. return true;
  87. }else{
  88. return false;
  89. }
  90. }catch (\Exception $e){
  91. Log::error('get user failed by access_token:'.$access_token.'|'.$e->getMessage());
  92. return false;
  93. }
  94. }
  95. }

//设置资源文件

  1. Route::middleware('auth:api')->get('/user', 'UserController@user'); //routes/api.php文件中设置
  2. php artisan make:controller UserController //创建文件
  1. class UserController extends Controller
  2. {
  3. public function user(Request $request)
  4. {
  5. return $request->user();
  6. }
  7. }

原文链接:http://www.cnblogs.com/SexyPhoenix/p/11769933.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号