当前位置: 首页 > 后端技术 > PHP

使用Laravel构建oauth2API接口与Unauthenticated解决方案

时间:2023-03-29 19:25:49 PHP

使用Laravel构建oauth2API接口需要laravel5.4或以上安装$composerrequirelaravel/passport在配置文件config/app的providers数组中注册Passport服务提供者。php:LaravelPassportPassportServiceProvider::class,执行迁移数据库后会生成oauth需要的表。$phpartisanmigrate注意在执行过程中可能会报错Syntaxerrororaccessviolation:1071Specifiedkeywastoolong;maxkeylengthis767byte这是因为Laravel5.4默认使用utf8mb4来编码utf8。字符的最大长度为3个字节。Support\ServiceProvider;useIlluminate\Support\Facades\Schema;classAppServiceProviderextendsServiceProvider{/***引导任何应用程序服务。**@returnvoid*/publicfunctionboot(){//Schema::defaultStringLength(191);}/***注册任何应用程序服务。**@returnvoid*/publicfunctionregister(){//}}另外,Mysql5.5.3只支持utf8mb4。还需要注意接下来执行$phpartisanpassport:install会生成两个客户端密钥。ClientID:1ClientSecret:AwDMcCs65rXkzF80wPaINx5fkoXEfa8lcuuPEvQKPasswordgrantclientcreatedsuccessfully.ClientID:2ClientSecret:KLlLijWk3hX2Ntfzo2iFPgwT4GyITpBjEuDozp5H配置这里只能配置访问令牌的生命周期。默认是永久的。配置使用Carbon\Carbon;在AuthServiceProvider中使用Laravel\Passport\Passport;/***注册所有的认证/授权服务。**@returnvoid*/publicfunctionboot(){$this->registerPolicies();护照::路线();Passport::tokensExpireIn(Carbon::now()->addDays(15));Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));}修改auth.php'guards'['driver']=>'passport'发放access_token发放应用场景我的用户想直接登录我在其他网站的账号,参考微信登录然后将对接第三方网站。用户选择第三方登录,跳转到我的页面,向用户请求权限。用户允许后,我会带一个代码回来。第三方网站使用此代码请求access_token。流程是请求token'client_id'=>'client-id','redirect_uri'=>'http://example.com/callback','response_type'=>'code','scope'=>'',用户允许稍后获取令牌代码$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'=>'',],]);隐式和第一种类似,就是省略代码,直接下发,主要用于JavaScript或移动应用中无法保存客户端登录认证信息的情况客户端证书主要用于机器间通信。直接用appid和appsecret交换token'=>'client-id','client_secret'=>'client-secret','scope'=>'your-scope',],]);privateaccesstoken程序中调用API时使用,如$user=App\User::find(1);//创建一个没有域的token...$token=$user->createToken('TokenName')->accessToken;//创建一个带域名的token...$token=$user->createToken('MyToken',['place-orders'])->accessToken;在调用api之前创建客户端的命令为$phpartisanpassport:clientpassword与private不同,其他相同$phpartisanpassport:client--password$phpartisanpassport:client--personal创建后获取client-id和client-secretcreationrouting5.4后目录结构发生变化,路由统一写在routes文件夹下。API路由是在api.php中编写的。确认路由后,就可以请求接口了。GETmethod/api/user'headers'=>['Accept'=>'application/json','Authorization'=>'Bearer'.$accessToken,],我这里写的时候遇到了一个问题,不管我怎么写request获取到的token,当我用它访问接口时,总是返回UnauthenticatedGOOGLE。我发现很多人我也遇到过这个问题。据说是token过期时间问题。添加Passport::tokensExpireIn(Carbon::now()->addDays(15));Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));这应该可以解决问题,但事实并非如此。待会再研究(已经解决,见下文)。这个问题取得了一些进展。目前通过用户授权发行代币的方式。前提是用户You必须登录,之前返回的是Unauthenticated。应该是因为用户没有登录,应用站跳转到授权站,此时用户需要登录。授权后,获取code,然后更改access_token。这个方法是可以的,可以正常获取到登录用户的信息。账号密码的token的获取方式也是一样的。可以通过站点前的id和secret方法更改token,然后使用token请求接口。有时候,路由无法通过auth或scope等中间件来验证,因为它们会先验证是否有登录。我们需要在app\Http\Kernel.php的$routeMiddleware中定义一个客户端API中间件'client_credentials'=>\Laravel\Passport\Http\Middleware\CheckClientCredentials::class,然后在路由Route::middleware('client_credentials')orRoute::middleware('client_credentials:scopename')这样可以不用登录直接调用api。参考文档https://laravel.com/docs/5.4/...