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

Laravel5.5使用Passport实现Auth认证

时间:2023-03-29 16:16:55 PHP

最近在写一个前后端分离的项目。本来想用Jwt-auth+Dingo来开发,但是有点麻烦,于是想到了Laravel的Passport和5.5新的ApiResource。LaravelPassport是一个打包的OAuth2服务器实现。以后我会单独写一篇关于OAuth2的文章,这里就不赘述了。让我们来看看如何安装它。安装并安装Passport1。在你的shell中执行以下命令composerrequirelaravel/passport如果你使用的Laravel版本低于5.5,你需要在config/app.php文件Laravel\Passport\PassportServiceProvider::的providers数组中手动??添加以下代码:class,2.运行迁移文件在你的shell中执行如下命令phpartisanmigratePassport服务提供者使用框架注册自己的迁移目录,所以注册服务后直接运行phpartisanmigrate生成Passport需要的数据表3.生成加密密钥在您的shellphpartisanpassport中执行以下命令:install此命令将创建生成安全访问令牌所需的加密密钥,同时,此命令还将创建访问令牌许可“个人”访问”客户端和“密码授权”。4.添加Trait添加LaravelPassportHasApiTokensTrait到AppUser模型}5.注册路由在AuthServiceProvider的boot方法中调用Passport::routes函数。classAuthServiceProviderextendsServiceProvider{publicfunctionboot(){$this->registerPolicies();护照::路线();}}如果你的程序需要前后端分离形式的OAuth认证,而不是多平台认证,那么你可以在routers()方法中传入一个匿名函数,自定义需要注册的路由.我这里是前后端分离的认证形式,所以我只需要对我的其中一个前端客户端提供Auth认证,所以我只注册获取Token,而且我还自定义了前缀名为了它。Passport::routes(function(RouteRegistrar$router){$router->forAccessTokens();},['prefix'=>'api/oauth']);6.更改guard驱动,配置文件config/auth.php授权guards中api的driver选项更改为passport。此调整将使您的应用程序使用Passport的TokenGuard来处理'guards'=>['web'=>['driver'=>'session','provider'=>在验证传入的API请求时'users',],'api'=>['driver'=>'passport','provider'=>'users',],],Passport安装到此为止,其余文档中提到的前端部分,因为我只需要使用它用于Auth认证,不需要实现完整的OAuth功能,所以我们根本不需要使用前端页面。为了方便Api返回数据,我封装了几个函数data'=>$respond]);}functionsucceed($respond='Requestsuccess!'){returnrespond(true,$respond);}functionfailed($respond='Requestfailed!'){returnrespond(false,$respond);}respond函数可以做基本的返回,succeed和failed在respond函数上重新封装,返回请求成功和请求失败的数据。然后我们需要使用一层代理。先说说使用代理的原因。Passport认证过程是从应用程序拿着主应用程序生成的ClientToken和用户输入的账号密码去请求主应用程序的PassportToken路由,获取访问令牌(accesstoken)和刷新令牌。(refreshtoken),然后就可以用获取到的accesstoken访问auth:api下的路由了。但是我们没有从属应用,前端分离前端去请求这个token。如果要从前端拉取accesstoken,需要在前端写入Clienttoken。这是很不合理的,所以我们可以在内部写一个代理,应用自己带着Clienttoken去请求自己获取accesstoken。这个可能有点迷惑,请求过程如下:1.前端用用户输入的账号密码向服务器请求2.服务端收到前端发来的账号和密码,添加Client_id和Client_token给它,然后用这些参数请求它自己的Passport认证路由,然后返回认证过的Accesstoken和refreshtoken。下面是代码实现。我在AppHttpControllersTraits下创建了ProxyHelpers的新Trait。当然这个功能是我根据自己的业务逻辑封装的。如果不适合你的业务逻辑,你可以自己调整。root()。'/api/oauth/令牌';$params=array_merge(config('passport.proxy'),['username'=>request('email'),'password'=>request('password'),]);$respond=$client->request('POST',$url,['form_params'=>$params]);}catch(RequestException$exception){thrownewUnauthorizedException('请求失败,服务器错误');}if($respond->getStatusCode()!==401){returnjson_decode($respond->getBody()->getContents(),true);}thrownewUnauthorizedException('账号或密码错误');}}config/passport.php内容如下['grant_type'=>env('OAUTH_GRANT_TYPE'),'client_id'=>env('OAUTH_CLIENT_ID'),'client_secret'=>env('OAUTH_CLIENT_SECRET'),'scope'=>env('OAUTH_SCOPE','*'),],];env文件内容如下OAUTH_GRANT_TYPE=passwordOAUTH_CLIENT_ID=2OAUTH_CLIENT_SECRET=2HaTQJF33Sx98HjcKDiSVWZjrhVYGgkHGP8XLG1OOAUTH_SCOPE=*我们需要的clienttoken就是useid为2的clienttoken,然后我们只需要在controller中弄错,然后调用$this->authenticate()获取认证成功的token。如果请求失败,可以使用catch捕获错误并抛出异常publicfunctionlogin(Request$request){$needs=$this->validate($request,rules('login'));$user=User::where('email',$needs['email'])->first();if(!$user){thrownewUnauthorizedException('该用户不存在');}$tokens=$this->authenticate();returnsucceed(['token'=>$tokens,'user'=>newUserResource($user)]);}获取到的token返回格式如下{"token_type":"Bearer","expires_in":31536000,"access_token":"token_str","refresh_token":"token_str"}完成所有这些后,您可以像这样从前端请求服务器axios.post('yourdomain/login',login_form)。then(resource=>{})如果请求成功,那么你会得到用户的信息和accesstoken,refreshtoken。然后你需要在你的前端http请求头中添加一个参数Authorizationaxios.defaults.headers.common['Authorization']=token.token_type+''+token.access_token然后在你需要的路由中使用中间使用auth认证文件auth:api,一切搞定~