利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法
利用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);
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
Schema::defaultStringLength(191);
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
另外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 Carbon\Carbon;
use Laravel\Passport\Passport;
/**
* 注册所有认证/授权服务.
*
* @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 = App\User::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等中间件去验证,因为他们会首先验证有没有登录。
我们需要在app\Http\Kernel.php 的 $routeMiddleware 里面定义一个客户端API的中间件
'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
然后在路由里面Route::middleware('client_credentials')
或者
Route::middleware('client_credentials:作用域名称')
这样就可以实现不登录直接调用api了
参考文档
利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法的更多相关文章
- Laravel POST请求API接口 使用validate表单验证返回欢迎页
突然遇到的问题 就是使用Laravel进行开发API接口的时候 发现在表单验证不通过的时候返回了登录页 猜测问题应该是因为表单验证失败后进行了重定向导致的 因为返回状态码200 网上找了好久没找到 ...
- JAVA联调接口跨域解决办法
JAVA联调接口跨域解决办法 第一种代码: HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,HttpStatus. ...
- 使用json-server搭建模拟api接口
转载:http://blog.csdn.net/adojayfan/article/details/55011674 作为前端和客户端开发人员,在后端还没有给出对应的api接口时,我们无法做测试. 这 ...
- 利用Metaweblog技术的API接口同步到多个博客网站(详细)
很早就有这个想法:自己有时候会用到多个博客,有些博客在一个网站上写完之后,要同步到其他博客网站,自己只能复制粘贴,感觉特别没意思,复制粘贴的麻木了.一直在想有哪些技术能实现一次写博,多站同步.最近网上 ...
- dvwa+xampp搭建显示乱码的问题:解决办法
如图,dvwa显示乱码,解决办法有两个:
- php 利用 json 传递数组之中文乱码最新解决办法
json好用,但是如果数据中有中文就会出乱子了,网上解决办法多半是设置utf-8编码或转换字符编码 以下是我的解决办法,利用php的urlencode.urldecode函数(其实也是一种转换编码吧) ...
- Laravel 的 JSON API 接口自动化测试
Laravel 自带了两种测试类型 Feature Test: 功能测试.针对类似接口这种流程性的测试. Unit Test: 单元测试.针对单个函数这种输入输出结果的测试. 新建一个 Feature ...
- App开发如何利用Fidder,在api接口还没有实现的情况下模拟数据,继续开发
相信app开发很多时候,都是等后台出接口,拿到数据调试错误.殊不知,我们完全可以不用等,只要有约定好的接口定义文档,借助工具就能做到,自己模拟数据返回~ 下面主要是在项目组开发过程中,使用F ...
- laravel JWTAuth实现api接口鉴权(基础篇)
官网:https://jwt-auth.readthedocs.io 参考:https://learnku.com/articles/10885/full-use-of-jwt#99529f 1.to ...
随机推荐
- Redis Server分布式缓存编程
这篇文章我将介绍如果用最简洁的方式配置Redis Server, 以及如何使用C#和它交互编程 一. 背景介绍 Redis是最快的key-value分布式缓存之一 缺点: 没有本地数据缓冲, 目前还没 ...
- 如何离线分析Kafka海量业务消息?1分钟快速为您支招
场景介绍 说起Kafka,许多使用者对它是又爱又恨.Kafka是一种分布式的.基于发布/订阅的消息系统,其极致体验让人欲罢不能,但操心的运维.复杂的安全策略.可靠性易用性的缺失等,仍需要使用者付出诸多 ...
- Oracle学习(18)【DBA向】:分布式数据库
分布式数据库 什么是分布数据库? l数据物理上被存放在网络的多个节点上,逻辑上是一个总体. 分布式数据库的独立性 l分布数据的独立性指用户不必关心数据怎样切割和存储,仅仅需关心他须要什么数据. Ora ...
- uml时序图的初印象-------Day64
近期有好多想法迫不及待的想去实现,但是其实是在那些最開始想的很明确,感觉会没问题的地方也总是会出现故障,导致稍微有些急躁,还是要淡定啊.又到了周末.明后天要收拾东西搬家,不知道宽带能不能顺利的给挪过去 ...
- java8--IO工具类(java疯狂讲义3复习笔记)
Paths类 public static void pathTest(){ Path path = Paths.get("~"); System.out.println(path) ...
- MySQL 5.7 Keywords and Reserved Words
https://dev.mysql.com/doc/refman/5.7/en/keywords.html#keywords-5-7-detailed-T
- JS Debug
任何一个编程者都少不了要去调试代码,不管你是高手还是菜鸟,调试程序都是一项必不可少的工作.一般来说调试程序是在编写代码之后或测试期修改Bug 时进行的,往往在调试代码期间更加能够体现出编程者的水平高低 ...
- Lightoj 1006 Hex-a-bonacci
Given a code (not optimized), and necessary inputs, you have to find the output of the code for the ...
- 【转】 Android Studio --“Cannot resolve symbol” 解决办法
Android Studio 无法识别同一个 package 里的其他类,将其显示为红色,但是 compile 没有问题.鼠标放上去后显示 “Cannot resolve symbol XXX”,重启 ...
- beyond compare 比较文本 standard alignment VS unaligned
在Rules里面 Standard Alignment 这种方式会比较找出相同的部分,可能会跨行找相同的 Unaligned 这种比较直接每一行之间相互比较,不跨行找相同的