资讯专栏INFORMATION COLUMN

利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法

anonymoussf / 4044人阅读

摘要:我们需要在的里面定义一个客户端的中间件然后在路由里面或者作用域名称这样就可以实现不登录直接调用了参考文档

利用Laravel 搭建oauth2 API接口 要求

laravel 5.4以上

安装

$ composer require laravel/passport

在配置文件 config/app.php 的providers 数组中注册 Passport 服务提供者:

LaravelPassportPassportServiceProvider::class,

迁移数据库 执行完后会生成oauth需要的表

$ php artisan migrate

这一步注意,执行的时候可能会报错

Syntax error or access violation: 1071 Specified key was too long; max key length is 767 byte

这是由于 Laravel5.4默认使用utf8mb4 编码
utf8 最大长度字符是3字节 utf8mb4是4字节

解决方法就是

数据库改用utf8mb4

AppServiceProvider.php里面加上Schema::defaultStringLength(191);


另外Mysql 5.5.3之后才支持utf8mb4也需要注意下

接下来执行

$ php artisan passport:install

会生成两个客户端密钥

Client ID: 1
Client Secret: AwDMcCs65rXkzF80wPaINx5fkoXEfa8lcuuPEvQK
Password grant client created successfully.
Client ID: 2
Client Secret: KLlLijWk3hX2Ntfzo2iFPgwT4GyITpBjEuDozp5H
配置

这里可以配置的只有access token的生命周期默认是永久的
在AuthServiceProvider中配置

use CarbonCarbon;
use LaravelPassportPassport;

/**
 * 注册所有认证/授权服务.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

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

修改auth.php
"guards"["driver"] => "passport"

发放access_token

颁发

应用场景 我的用户,在别的网站想用我的账号直接登录,参考微信登录。那么第三方网站就要对接过来,用户选择第三方登录,跳转到我的页面,询问用户是否允许,用户允许以后我会带一个code回去,第三方网站用这个code请求access_token

流程是

请求令牌

    
    "client_id" => "client-id",
    "redirect_uri" => "http://example.com/callback",
    "response_type" => "code",
    "scope" => "",

用户允许以后拿到code换token

 $response = $http->post("http://your-app.com/oauth/token", [
        "form_params" => [
            "grant_type" => "authorization_code",
            "client_id" => "client-id",
            "client_secret" => "client-secret",
            "redirect_uri" => "http://example.com/callback",
            "code" => $request->code,
        ],
    ]);

token如果过期了,可以刷新

$response = $http->post("http://your-app.com/oauth/token", [
    "form_params" => [
        "grant_type" => "refresh_token",
        "refresh_token" => "the-refresh-token",
        "client_id" => "client-id",
        "client_secret" => "client-secret",
        "scope" => "",
    ],
]);

账号密码

这个主要是用于APP(我自己的),用户通过app输入账号和密码,我用账号密码校验正确了就发送access_token

$response = $http->post("http://your-app.com/oauth/token", [
    "form_params" => [
        "grant_type" => "password",
        "client_id" => "client-id",
        "client_secret" => "client-secret",
        "username" => "taylor@laravel.com",
        "password" => "my-password",
        "scope" => "",
    ],
]);

隐式

这种跟第一种差不多,就是省去了code 直接发放,主要用于

JavaScript 或移动应用中客户端登录认证信息不能保存时

客户端证书

这种主要用于机器之间的通信
直接用appid 和 appsecret 换令牌

$response = $guzzle->post("http://your-app.com/oauth/token", [
    "form_params" => [
        "grant_type" => "client_credentials",
        "client_id" => "client-id",
        "client_secret" => "client-secret",
        "scope" => "your-scope",
    ],
]);

私人访问令牌

这个用于在程序里面调用API的时候
比如

$user = AppUser::find(1);

// 创建一个不带域的令牌...
$token = $user->createToken("Token Name")->accessToken;

// 创建一个带域的令牌...
$token = $user->createToken("My Token", ["place-orders"])->accessToken;

在调用api之前需要创建client
创建命令是
$ php artisan passport:client

密码和私人的不同其他都一样

$ php artisan passport:client --password
$ php artisan passport:client --personal

创建好后获得client-id和client-secret

创建路由

5.4以后目录结构发生变化,路由统一写在routes文件夹下。
API的路由都写在api.php

确定好路由就可以请求接口了

GET 方式
    /api/user
    "headers" => [
        "Accept" => "application/json",
        "Authorization" => "Bearer ".$accessToken,
    ],

写到这里遇到一个问题

就是无论怎样请求 获取到的token 用来访问接口的时候 总是返回
Unauthenticated

GOOGLE了下发现好多人也遇到这个问题,据说是token过期时间的问题

在AuthServiceProvider boot里面加上

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

这样应该会解决,然而并没有,这里等以后一时间再研究下(已解决 见下文)

这个问题有了一定进展

目前通过用户授权颁发令牌的方式通过了

前提是用户必须登录,之前返回Unauthenticated 应该是因为用户未登录

在应用站跳转到授权站的时候,此时用户需登录状态,授权以后拿到code再来换access_token 这个方式OK的,可以正常获取登录用户的信息

账号密码获取令牌的方式也一样可以通过

站点之前通过 id 和 secret的方式换token,然后拿token请求接口这种方式目前还不行

坑爹啊,官方文档没写全

通过 client_credentials 方式获取token,请求接口的时候,路由不能用auth或者scope等中间件去验证,因为他们会首先验证有没有登录。

我们需要在appHttpKernel.php 的 $routeMiddleware 里面定义一个客户端API的中间件

"client_credentials" => LaravelPassportHttpMiddlewareCheckClientCredentials::class,

然后在路由里面
Route::middleware("client_credentials")

或者

Route::middleware("client_credentials:作用域名称")

这样就可以实现不登录直接调用api了

参考文档

https://laravel.com/docs/5.4/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22544.html

相关文章

  • PHP / Laravel API 开发推荐阅读清单

    showImg(https://segmentfault.com/img/bV6aHV?w=1280&h=800); 社区优秀文章 Laravel 5.5+passport 放弃 dingo 开发 API 实战,让 API 开发更省心 - 自造车轮。 API 文档神器 Swagger 介绍及在 PHP 项目中使用 - API 文档撰写方案 推荐 Laravel API 项目必须使用的 8 个...

    shmily 评论0 收藏0
  • Laravel Passport里的授权类型介绍

    摘要:模糊授权,跟上面的认证码授权类似,不同的是,我们的资源服务器,返回的直接就是准入令牌,而不是认证码。 本文来自pilishen.com----原文链接; 欢迎来和pilishen一起学习php&Laravel;学习群:109256050 OAuth2是一个安全框架,控制着程序受保护部分的准入,主要是控制不同的客户端如何来调取API,保证它们在请求相应资源的时候有相应的权限。 Larav...

    RobinTang 评论0 收藏0
  • 学习 Lumen 用户认证 (一)

    摘要:在开发中,用户认证是核心,是数据是否有保障的前提,目前主要有两种常用方式进行用户认证和。附是为了在网络应用环境间传递声明而执行的一种基于的开放标准。 好久没写 PHP 代码了,尤其是 Lumen,我是 Lumen 的忠实用户,自从面世开始,我就将 Lumen 作为我 API 的主要框架使用。 但说到 API,不得不说的一个概念:「前后端分离」,现在越来越多的团队都采用前后端分离,彻底解...

    wangzy2019 评论0 收藏0
  • 小白的边学边写,一个基于laravel的APP接口API】(一)

    摘要:前期准备原文地址前言,为什么做以及要做个啥本人姓小名白,不折不扣编程届小白一名,但是自从大一那会儿接触到编程这件奇妙的事情,就完完全全的陷入的程序的世界。框架,是我最喜欢的框架了,没有之一。 前期准备 原文地址前言,为什么做以及要做个啥本人姓小名白,不折不扣编程届小白一名,但是自从大一那会儿接触到编程这件奇妙的事情,就完完全全的陷入的程序的世界。这不,最近又开始折腾APP了,话说现在开...

    Nosee 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<