Single sign - API authentication system Passport (II)

installation

composer require laravel/passport=~4.0

Notes:
1) ensure that the system is installed unzip, zip commands.
2) composer appears mounted Authentication required (packagist.phpcomposer.com) problem, modify the source composer.json, repositories.packagist.url = https://packagist.laravel-china.org.

Registration Service Providers

Added providers array config / app.php in Laravel \ Passport \ PassportServiceProvider :: class

Database migration

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

Generate an encryption Kin

 php artisan passport:install  

1, generate oauth-private.key (used to build an authentication server), oauth-public.key (used to build the resource server)
2, oauth_clients database generation "personal visit" client and "password authorization] two data.

Configuration Passport (refer to the official documentation)

In the Model, we need to increase HasApiTokens class
in AuthServiceProvider, add "Passport :: routes ()"
in auth.php, change the authentication mode to passport api

The client application access token, and a private (two ways)

1. order form (convenient customer registration)
php artisan passport:client

8

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

// Register the resources / assets / js / app.js file, remember to put new Vue top

Vue.component(
    'passport-clients',
    require('./components/passport/Clients.vue')
);

Vue.component(
    'passport-authorized-clients',
    require('./components/passport/AuthorizedClients.vue')
);

Vue.component(
    'passport-personal-access-tokens',
    require('./components/passport/PersonalAccessTokens.vue')
);

// compiler front-end resources

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

After compiling resources on public / js / app.js down

// assembly into the application template (remember app.js after the introduction compilation)

<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>

9
The above authentication server have been set up to complete

Login achieve third-party applications

1. Application Client

10
Callback address http: //third.plat.goods/dew/sso

Apply for authorization code and access token

// get the authorization code code (the first interaction)

$query = http_build_query(array(
        'client_id' => 3,
        'redirect_uri' => 'http://third.plat.goods/dew/sso', //地址必须为上面的回调地址
        'response_type' => 'code',  //固定值
        'scope' => '',
        'state' => urlencode('http://laravel.plat.goods/user')   //可以放用户访问的地址。
));

return redirect('http://laravel.plat.goods/oauth/authorize?'.$query);  ///laravel.plat.goods为上面认证服务器

11
// get access token access token and user information request to the resource server
after the authorization will be redirected callback address

Route::get('/dew/sso', 'SSOController@callback');  //路由文件里添加
php artisan make:controller SSOController //创建文件
<?php
namespace App\Http\Controllers;

use App\Models\User;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class SSOController extends Controller
{
    protected $http;
    public function __construct()
    {
        $this->http = new Client();
    }

    /**
     * 获取授权码后的回调URL
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function callback(Request $request)
    {

        $token = $this->token($request); //第二次交互
        $login = $this->login($token);//第三次交互

        if($login){

            if($request_url = $request->input('state', null)){
                $request->session()->put('url.intended', urldecode($request_url));
            }
            return redirect()->intended();  //跳转到 http://laravel.plat.goods/user
        }else{
            return redirect()->to('http://laravel.plat.com/home/public/login'); //服务提供商网站必须登录
        }
    }

    /**
     * 获取access token
     * @param $request
     * @return array|mixed
     */
    protected function token($request)
    {
        $code = $request->code;
        if($code) {

            try {

                $response = $this->http->post('http://laravel.plat.goods/oauth/token', [
                    'form_params' => [
                        'grant_type' => 'authorization_code',  //固定值
                        'client_id' => 3,
                        'client_secret' => 'UihXNHoSqohdtQ8Js6Av7AOyk3GBNB9rJziDPaWf',
                        'redirect_uri' => 'http://third.plat.goods/dew/sso',
                        'code' => $code,
                    ],
                ]);

                $response_data = json_decode((string)$response->getBody(), true);

                return $response_data;
            } catch (\Exception $e) {

                Log::error('get token by code failed: '.$code.' - '.$e->getMessage().' - '.$e->getTraceAsString());

                return [];
            }
        }else{

            return [];
        }

    }
    /**
     * 通过token获取用户信息,并进行登录操作
     * @param $token
     * @return bool
     */
    protected function login($token)
    {
        if(empty($token)) return false;

        $access_token = $token['access_token'];
        try {
           
           // 资源服务器和认证服务器放在了一起,可以独立。
            $response = $this->http->request('GET', 'http://laravel.plat.goods/api/user', [
                'headers' => [
                    'Accept' => 'application/json',
                    'Authorization' => $token['token_type'] . ' ' . $access_token,
                ]
            ]);
            $users_body = $response->getBody();
            $data = json_decode($users_body, true);
            if($data) {
                $user = new User($data);

                //because of employee_id is guarded
                $user->setAttribute($user->getKeyName(), $data['employee_id']);
                //login user in my system
                auth()->login($user, false);

                return true;
            }else{

                return false;
            }
        }catch (\Exception $e){

            Log::error('get user failed by access_token:'.$access_token.'|'.$e->getMessage());
            return false;
        }
    }
}

// set the resource file

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

Guess you like

Origin www.cnblogs.com/SexyPhoenix/p/11769933.html