2018年5月

1、通过Composer安装Passport

composer require laravel/passport

2、在配置文件app.php中的providers数组中注册Passport服务:

Laravel\Passport\PassportServiceProvider::class,

3、生成用于存放客户端和访问令牌的数据表

php artisan migrate

4、创建token所需的加密键

php artisan passport:install

5、添加LaravelPassportHasApiTokens trait 到 AppUser 模型

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;


class User extends Authenticatable
{
    use HasApiTokens,Notifiable;
    ......    
}

6、在 AuthServiceProvider 的 boot 方法中调用 Passport::routes 方法

        Passport::routes(
             //只开放 /oauth/token);
            function(RouteRegistrar $router){
                $router->forAccessTokens();
            },
            ['prefix' => 'api']

7、设置 api 认证 guard 的 driver 选项为 passport

'guards' => [
    ......
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

8、配置更短的令牌生命周期,可以使用 tokensExpireIn 和 refreshTokensExpireIn 方法

    Passport::tokensExpireIn(Carbon::now()->addDays(15));
    Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));

9、创建ApiController


namespace App\Http\Controllers\Api;

use App\Http\Traits\ApiResponse;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;

class ApiController extends Controller
{
    use  AuthenticatesUsers;
    use ApiResponse;

    public function __construct()
    {
        $this->middleware('api');
    }

    //调用认证接口获取授权码
    protected function authenticateClient(Request $request)
    {
        $credentials = $this->credentials($request);

        $data = $request->all();
        if ($request->refresh_token) {
            $request->request->add([
                'grant_type' => $data['grant_type'],
                'client_id' => $data['client_id'],
                'client_secret' => $data['client_secret'],
                'refresh_token' => $data['refresh_token'],
                'scope' => ''
            ]);
        } else {
            $request->request->add([
                'grant_type' => $data['grant_type'],
                'client_id' => $data['client_id'],
                'client_secret' => $data['client_secret'],
                'email' => $data['email'],
                'password' => $data['password'],
                'scope' => ''
            ]);
        }

        $proxy = Request::create(
            'oauth/token',
            'POST'
        );

        $response = \Route::dispatch($proxy);

        return $response;
    }
    /*
     *重写AuthenticatesUsers部分功能函数来实现整个完整的授权流程
     */
    protected function authenticated(Request $request)
    {
        return $this->authenticateClient($request);
    }

    protected function sendLoginResponse(Request $request)
    {
        $this->clearLoginAttempts($request);

        return $this->authenticated($request);
    }

    protected function sendFailedLoginResponse(Request $request)
    {
        $msg = $request['errors'];
        $code = $request['code'];
        return $this->failed($msg,$code);
    }
}

10、创建LoginController

<?php
/**
 * Created by PhpStorm.
 * User: hzh
 * Date: 2018/5/1
 * Time: 14:17
 */
namespace App\Http\Controllers\Api;

use App\Http\Controllers\Api\ApiController;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Passport\Token;
use Validator;


class LoginController extends ApiController
{
    protected $successStatus = 200;

    public function __construct()
    {
        $this->middleware('auth:api')->only([
            'logout'
        ]);
    }

    // 登录用户名标示为email字段
    public function username()
    {
        return 'email';
    }

    public function login(Request $request){

        $user = $request->only(['password','email']);
        if(count($user) != 2)return response()->json(['error_code'=>203,'error'=>'Missing Parameter']);
        if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
            $user = Auth::user();
            $success['token'] =  $user->createToken('Imagingbay')->accessToken;
            $success['email'] =  $user->email;
            $success['uid'] =  $user->id;
            return response()->json(['error_code'=>0,'data' => $success], 200)->withHeaders(
                [
                    'Accept' => 'application/json',
                    'Authorization' => 'Bearer '.$success['token']
                ]
            );
        }
        else{
            return response()->json(['error_code'=>202,'error'=>'Unauthorised'], 401);
        }
    }

    /**
     * Register api
     *
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255|unique:user_ordinary|min:4',
            'password' => 'required|string|min:6|confirmed',
            'password_confirmation' => 'required|same:password',
        ]);

        if ($validator->fails()) {
            return response()->json(['error'=>$validator->errors()], 401);
        }

        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] =  $user->createToken('Imagingbay')->accessToken;
        $success['email'] =  $user->email;
        $success['uid'] =  $user->id;

        return response()->json(['error_code'=>0,'data'=>$success], $this->successStatus);
    }

    /*
     * 注销账号
     */
    public function logout(Request $request)
    {
        'status_code' => 200, 'data' => null]);

        $user = $this->guard()->user();
        if (empty($user)) {
            return response()->json(['message' => '暂未登录', 'error_code' => 20403, 'data' => null]);
        }

        // 获取当前登陆用户的token并且将其删除
        $token = Auth::guard('api')->user()->token();
        if (empty($token)) {
            return response()->json(['message' => '暂无有效令牌', 'error_code' => 20403, 'data' => null]);
        }

        if (!empty($token->delete())) {
            return response()->json(['message' => '退出成功', 'error_code' => 0, 'data' => null]);
        } else {
            return response()->json(['message' => '退出失败', 'error_code' => 0, 'data' => null]);
        }
    }


    /**
     * details api
     *
     * @return \Illuminate\Http\Response
     */
    public function getDetails()
    {
        $user = Auth::user();
        return response()->json(['success' => $user], $this->successStatus);
    }

}

11、添加两个监听器

        'Laravel\Passport\Events\AccessTokenCreated' => [
            'App\Listeners\RevokeOldTokens',
        ],

        'Laravel\Passport\Events\RefreshTokenCreated' => [
            'App\Listeners\PruneOldTokens',
        ],
        //执行php artisan event:generate创建监听器

12、在AppListenersRevokeOldTokens的handle中删除失效token:

        DB::table('oauth_access_tokens')
            ->where('id', '<>', $event->tokenId)
            ->where('user_id', $event->userId)
            ->where('client_id', $event->clientId)
            ->delete();

13、构建路由

Route::group([
    'prefix'=>'/v1',
    'middleware' => ['api'],
], function () {
    Route::post('user/login','Api\LoginController@login');
    Route::post('user/register','Api\LoginController@register');
});
Route::group([
    'prefix'=>'/v1',
    'middleware' => ['auth:api'],
    //指定需要传入有效访问令牌的 auth:api 中间件
], function () {
    Route::get('user/logout','Api\LoginController@logout');
    Route::get('user/info','User\IndexController@getInfo');//显示个人信息
});

测试:

1、注册
注册
2、登录
登录
3、获取用户信息
获取用户信息
4、注销
注销