Laravellaravel自学

手摸手,教你使用 laravel-passport 实现 oau

2018-03-31  本文已影响708人  王宝花

知识点概括

  1. oauth 2.0 概念
  2. laravel passport 基本使用
  3. guzzlehttp 组件使用

环境介绍

  1. 使用 laradock 作为 laravel 的开发环境

PHP 7.2、MySQL 5.7

  1. Node 环境

node 9.8、npm 5.6

项目架构

  1. Server 项目用于搭建 验证授权服务器
  2. Client 项目用于 第三方应用
Oauth 2.0 验证流程示意图(引用于:阮一峰博客)

设计逻辑

实现类似与微信授权登陆的逻辑。
挡在微信中进入其它网页时,会出现类似授权的页面,当点击授权后即可获取用户的信息。


image.png

Server 项目搭建

  1. 首先使用命令创建 Server 项目
composer create-project laravel/laravel --prefer-dist server
  1. 配置数据库
# .env
...
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=server
DB_USERNAME=root
DB_PASSWORD=root
...

laradock 中 host 必须填写 mysql,自动转发到 mysql 容器中

  1. 安装laravel/passport
composer require laravel/passport

laravel 5.5 以后有自动发现机制,不需要配置 provider,低于该版本请按照手册自行配置。

  1. 执行数据库迁移,并添加 auth 脚手架。
$ php artisan migrate
$ php artisan make:auth

当执行完 make:auth 后首页上就会出现注册与登录。

image.png
  1. 生成 passport key 以及一些 password keys
php artisan passport:install
image.png
  1. 配置 config 文件
    将 api 的driver 更换为 passport
# config/auth.config
...
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

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

这一步是实现 API Auth 授权中间件默认使用的驱动

  1. User 使用 Password 提供的 Trait
# App\User
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
  use HasApiTokens;
  ...
}
  1. 配置 Passport 相关路由信息
# App\Providers\AuthServiceProvider
...
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
     ...
    public function boot()
    {
        $this->registerPolicies();

        // Passport 路由
        Passport::routes();
        // Passport Token 过期时间
        Passport::tokensExpireIn(Carbon::now()->addDay(15));
        // Passport Refresh Token 过期时间
        Passport::refreshTokensExpireIn(Carbon::now()->addDay(30));
    }
}
  1. 生成前端脚手架,默认提供了 vue 相关模板,需要使用到 node
php artisan vendor:publish  --tag=passport-components
image.png
  1. 使用 npm 或 cnpm 命令安装 package.json 的相关依赖
    composer.json 与 package.json 类似,npm 与 composer 类似。使用 npm 必须安装 node 环境。npm 与 composer 类似,境外资源拉取非常慢,所以推荐使用淘宝镜像。具体设置方法请 Google。
npm install 
image.png
  1. 然后将 component 组件注册到 vue 的根实例中
# resources/assets/js/app.js
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')
);
image.png
  1. 编译文件,生成 app.js 和 app.css
npm run dev
image.png

有一些同学可能会存在相关问题,比如笔者就遇到一个bug。Module build failed: ReferenceError: Unknown plugin "transform-runtime",当遇到这个bug时第一时间google了一下,然后各种无法解决,仔细一看,原来是项目的上一级目录中存在一个 .babelrc文件,该文件 上一个 vue 项目的残余(没删除干净),然后删除之后就可以了。
这里笔者要说明的是:遇到问题不要紧张,首先看一下报错的信息,如果是 依赖没安装成功就删除 node_modules,重新安装下。如果是存在其它 bug,首先看看是不是本项目的,如果不是就删除它,如果是的话那么就 google 一下,查找一下解决方式,或者你可以留言。

  1. 这时,你就需要可以在 blade 模板里面引入编译好的 css 和 js 就可以了。
# resources/view/passport.blade.php
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
    <!-- Vue 默认绑定的根节点 -->
    <div id="app" class="container">
        <passport-clients></passport-clients>
        <passport-authorized-clients></passport-authorized-clients>
        <passport-personal-access-tokens></passport-personal-access-tokens>
    </div>

    <!-- 必须放在 根节点 之后,否则无法正常解析-->
    <script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
  1. 添加路由
# routes/web.php
Route::get('/passport', function () {
    return view('passport');
});
  1. 访问路由
server.test/passport
image.png

页面渲染,但是报错了 401 错误,这说明必须登录之后才能访问该路由。那么进入首页登录一下即可,没有账号就注册一个。


image.png
  1. 成功,并且无报错信息


    image.png
  2. 创建一个 Client


    image.png
image.png
  1. 使用 浏览器 测试一下
http://server.test/oauth/authorize?client_id=your_client_id&redirect_uri=your_redirect_uri&response_type=code&scope=*

将 client_id 和 redirect_uri 替换成你自己的即可

image.png
  1. 响应数据
http://client.test/authorizations?code=def50200b4bd56c76cf885df8f4871b1325aa23571c07fe149086c4a3795c7b6e286d19aef3101330fcaa7e19a8bebaabf4a3cb4cdfa6208934a4d42db4e5f2eee1ef0a78ae6da976da9764c75d7561f43cd12d3a2aacc20b94cc12b71aa2b7464c44438524e8b73c256b655168ed6087da8a82c011c1f86deb3a72cf30a4eba955579efce5cf007993c13ad1783beb43bb30980f5ac54b0a559148df3182839ee6522c0175eb24ce917f36a2b1bb70b4278dc29640d8251a83a9e8a58c559b8b7304e2edfaeb24c9f248f1eb0187ecff76ecb8ebdbd57a1da91ce4c84142946065cbdb5187e4f92f012ce49497f6fd471c2a9a6538f89a8194dda8b976f42377fa1b429237b7bf2606ab64fe459532fba35f61fb8262efc8b4931edcaaf0ff6ec87dba9894916a90ada15c9fd8f44a7520996e44bfa38fd8ae2c719cb098e673887eddbb2a01b5af9f7c062ffb991536cbdeff275a3b7a2556c595998eec98dda063759aa3d
  1. 通过 code 获取 access_token


    image.png

把 client_id 和 client_secret 更换为你自己的

  1. 响应数据解读
    token_type: Bearer 是 Oauth 2.0 的一种认证模式,一般均为此。
    expires_in: 过期时间
    access_token: 通讯密钥
    refersh_token:刷新Token,是在 access_token 过期后,可以用此更换新的 access_token

还记得我们在 AuthProvider中设置的过期时间么?token 过期时间比 refresh_token 过期时间要短,我们设置的是 15天 和 30 天。

  1. 这时就可以拿着 access_token 去读取用户信息了
    首先,定义一个 API 路由
# routes/api.php

Route::middleware('auth:api')->get('/user', function (Request $request) {
    $user = \Auth::guard('api')->user();
    return response()->json($user);
});

比如,在 API 路由中去读取用户信息,使用 Postman 测试一下。


image.png image.png
  1. 恭喜,基本完成了。
    当然,笔者做的实验是利用 client 去实现 postman 的功能,但是发现 postman 更好用。client 端的代码其实就是做了一层转发的功能,让服务器保存 client_secret 更加安全。但基于实验,你完全可以使用 postman。

这里笔者只是基本完成了 laravel-passport 的授权模式, 如果还要更深的研究,你可以留言,我可以进行更加具体的教程解读。

这里笔者将代码放在 github上,如果你搭不起环境,可以直接拿来做实验 laravel-passport-test

Client 端代码
上一篇下一篇

猜你喜欢

热点阅读