资讯专栏INFORMATION COLUMN

Laravel 5.5 使用 Passport 实现 Auth 认证

miguel.jiang / 2269人阅读

摘要:最近在写一个前后端分离项目,本来想用开发的,但是略感笨重,于是想到了的和新出的。更改看守器驱动将配置文件中授权看守器的的选项改为。然后在你的前端请求里需要加入一个参数然后在你需要使用到认证的路由里使用中间件,一切就大功告成啦

最近在写一个前后端分离项目,本来想用 Jwt-auth + Dingo 开发的,但是略感笨重,于是想到了 Laravel 的 Passport 和 5.5 新出的 Api Resource。Laravel Passport 是一套已经封装好的 OAuth2 服务端实现,关于 OAuth2 我以后我会多带带写一篇文章,所以这里就不细说了,先来看看怎么安装它吧。

安装 安装 Passport

1.在你的 Shell 中执行以下命令

composer require laravel/passport

如果你使用的 Laravel 版本是 5.5 以下,你需要手动在 config/app.php 文件 providers 数组中加入如下代码

LaravelPassportPassportServiceProvider::class,

2.运行迁移文件

在你的 Shell 中执行如下命令

php artisan migrate

Passport 服务提供器使用框架注册自己的迁移目录,因此在注册服务后,你可以直接运行 php artisan migrate 来为 Passport 生成所需的数据表

3.生成加密密钥

在你的 Shell 中执行如下命令

php artisan passport:install

此命令会创建生成安全访问令牌时所需的加密密钥,同时,这条命令也会创建用于生成访问令牌的「个人访问」客户端和「密码授权」。

4.添加 Trait

将 LaravelPassportHasApiTokens Trait 添加到 AppUser 模型中


5.注册路由

在 AuthServiceProvider 的 boot 方法中调用 Passport::routes 函数。

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

        Passport::routes();
    }
}

如果你的程序是需要前后端分离形式的OAuth认证而不是多平台认证那么你可以在routers()方法中传递一个匿名函数来自定定义自己需要注册的路由,我这里是前后端分离的认证形式,因此我只需要对我的前端一个Client提供Auth的认证,所以我只注册了获取Token的路由,同时我还为它自定义了前缀名。

Passport::routes(function(RouteRegistrar $router) {
    $router->forAccessTokens();
},["prefix" => "api/oauth"]);

6.更改看守器驱动

将配置文件 config/auth.php 中授权看守器 guards 的 api 的 driver 选项改为 passport。此调整会让你的应用程序在在验证传入的 API 的请求时使用 Passport 的 TokenGuard 来处理

"guards" => [
    "web" => [
        "driver" => "session",
        "provider" => "users",
    ],

    "api" => [
        "driver" => "passport",
        "provider" => "users",
    ],
],

至此 Passport 已经安装完成,剩下的文档里所讲到的前端部分的话,由于我是只需要使用它做 Auth 的认证,并不需要实现完整的 OAuth 功能,所以我们完全可以不使用前端页面。

使用

为了 Api 返回数据方便,我封装了几个函数

function respond($status, $respond)
{
    return response()->json(["status" => $status, is_string($respond) ? "message" : "data" => $respond]);
}

function succeed($respond = "Request success!")
{
    return respond(true, $respond);
}

function failed($respond = "Request failed!")
{
    return respond(false, $respond);
}

respond 函数可以做基本返回,succeed 和 failed 是在 respond 函数上做的再次封装,用以返回请求成功和请求失败数据。

然后我们需要使用一层代理。

先说一下使用代理的原因,Passport 认证的流程是 从属应用带着 主应用
生成的 Client Token 和 用户输入的账号密码去请求主应用的 Passport Token 路由,以获得 access token (访问令牌) 和 refresh token (刷新令牌),然后带着得到的 access token 就可以访问 auth:api 下的路由了。但是我们并没有从属应用,是由前后端分离的前端来请求这个token,如果从前端想来拉取这个 access token 就需要把 Client token 写死在前端里,这样是很不合理的,所以我们可以在内部写一个代理,由应用自身带着 Client token 去请求自身以获取 access token,这样说可能有一点绕,大概请求过程是下面这个样子

1.前端带着用户输入的账号密码请求服务端
2.服务端带着从前端接收到账号与密码,并在其中添加 Client_id 与 Client_token,然后带着这些参数请求自身的 Passport 认证路由,然后返回认证后的 Access token 与 refresh token

下面是代码实现,我在 AppHttpControllersTraits 下新建了一个 ProxyHelpers 的 Trait,当然,这个函数是我根据我的业务逻辑自己封装的,如果不适合你的业务逻辑你可以自行调整。

root() . "/api/oauth/token";

            $params = array_merge(config("passport.proxy"), [
                "username" => request("email"),
                "password" => request("password"),
            ]);

            $respond = $client->request("POST", $url, ["form_params" => $params]);
        } catch (RequestException $exception) {
            throw  new UnauthorizedException("请求失败,服务器错误");
        }

        if ($respond->getStatusCode() !== 401) {
            return json_decode($respond->getBody()->getContents(), true);
        }

        throw new UnauthorizedException("账号或密码错误");
    }
}

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=password
OAUTH_CLIENT_ID=2
OAUTH_CLIENT_SECRET=2HaTQJF33Sx98HjcKDiSVWZjrhVYGgkHGP8XLG1O
OAUTH_SCOPE=*

我们需要用到的 client token 是 id 为 2 的 client token,不要搞错了哟~

然后我们只需要在控制器中 use 这个 Trait,然后调用 $this->authenticate() 就可以得到认证成功的 token,如果请求失败的话,你可以使用 catch 来捕捉错误抛出异常。

 public function login(Request $request)
{
        $needs = $this->validate($request, rules("login"));

        $user = User::where("email", $needs["email"])->first();

        if (!$user) {
            throw new UnauthorizedException("此用户不存在");
        }

        $tokens = $this->authenticate();

        return succeed(["token" => $tokens, "user" => new UserResource($user)]);
}

得到的 tokens 返回如以下格式

{
    "token_type": "Bearer",
    "expires_in": 31536000,
    "access_token": "token_str",
    "refresh_token": "token_str"
}

做完这一切后你就可以在前端向这样子请求服务端了

axios.post("yourdomain/login",login_form).then(resource => {
    
})

如果请求成功,那么你将会得到 用户的信息和 access token,refresh token。

然后在你的前端 http 请求 header 里需要加入一个参数 Authorization

 axios.defaults.headers.common["Authorization"] = token.token_type + " " + token.access_token

然后在你需要使用到 auth 认证的路由里使用中间件 auth:api,一切就大功告成啦~

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

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

相关文章

  • Laravel 5.5 使用 Jwt-Auth 实现 API 用户认证以及无痛刷新访问令牌

    摘要:默认的时间为周。大概意思就是如果用户有一个,那么他可以带着他的过来领取新的,直到周的时间后,他便无法继续刷新了,需要重新登录。指定在刷新令牌时要保留的声明密钥。为了使令牌无效,您必须启用黑名单。指定用于对用户进行身份验证的提供程序。 showImg(https://segmentfault.com/img/remote/1460000012606251?w=1920&h=1280); ...

    xavier 评论0 收藏0
  • 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 做 API 认证

    摘要:使用进行测试注册接口,注册成功后返回与用户名登录接口详情接口参考了简书浪来了的认证应用实战 安装larave laravel new passport_demo cd passport_demo && composer install 将 .env 中数据库配置修改为自己的数据库配置 DB_DATABASE=homestead DB_USERNAME=homestead DB_P...

    whinc 评论0 收藏0
  • laravel5.4 中auth:api中间件通过passport认证,通过传递参数authoriz

    摘要:的的认证登录,默认是通过传入头的方式验证进行认证,认证代码如下如果不想通过头传递,用传递参数的方式,实现方式在的里面将参数的,先接受再赋值到里面即可,也能到达验证的目的 laravel passport的auth:api的认证登录,默认是通过传入header头的方式验证accessToken进行认证,认证代码如下showImg(https://segmentfault.com/img/...

    hosition 评论0 收藏0
  • Laravel Passport API 认证使用小结

    摘要:看到社区常有人问用于密码验证方式来获取的问题,刚好我最近一个项目使用,也是使用的密码授权来做验证,对于如何做登录登出,以及多账号系统的认证等常用场景做一下简单的使用小总结。 看到Laravel-China社区常有人问Laravel Passport用于密码验证方式来获取Token的问题,刚好我最近一个API项目使用Laravel Dingo Api+Passport,也是使用Oauth...

    Panda 评论0 收藏0

发表评论

0条评论

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