Laravel 5.4 下面Custom Auth的一些备忘

  1. 1. 配置自定义的用户登录Provider
  • 注册该Provider
  • 实现custom的Provider
  • Laravel 提供了强大的用户登录功能。建立起Application之后直接 php artisan make:auth 就可以建立起一个最基本的基于用户邮箱密码登录的MiddleWare。
    但是有时候,当我们需要进行二次开发,当数据库并不在本地,用户信息都需要通过API获取的时候,我们就需要按照laravel的接口自己来写用户的登录了。
    这次我们需要从一个由Yar 的rpc api提供的接口中去获取用户信息。

    配置自定义的用户登录Provider

    1
    2
    3
    4
    5
    //config/auth.php
    'providers' => [
    'users' => [
    'driver' => 'yar_provider',
    ],

    注册该Provider

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?php
    namespace App\Auth;
    use Auth;
    use App\Auth\YarUserProvider;
    use Illuminate\Support\ServiceProvider;
    class AuthServiceProvider extends ServiceProvider
    {
    /**
    * Perform post-registration booting of services.
    *
    * @return void
    */
    public function boot()
    {
    Auth::provider('yar_provider', function($app, array $config) {
    return new YarUserProvider();
    });
    }

    }

    可以看到我们需要返回一个YarUserProvider的object。在这个Provider中,我们需要完成的任务就是调用API获取用户信息并完成用户的验证。

    实现custom的Provider

    首先看一下我们需要实现的接口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider {

    public function retrieveById($identifier);
    public function retrieveByToken($identifier, $token); //用于没有session的情况,比如API的http的header。这次无视。
    public function updateRememberToken(Authenticatable $user, $token); // 暂时不管
    public function retrieveByCredentials(array $credentials);
    public function validateCredentials(Authenticatable $user, array $credentials);

    }

    retrieveById($identifier)一般用户当我们刷新页面的时候,我们的app从session中获取用户id,然后通过我们的实现,用这个id来获取用户信息。
    这次我们需要做的仅仅是调用Yar的API(传递用户id,返回用户信息的API)。

    retrieveByCredentials(array $credentials);用户用户登录时候提供用户名(或者邮箱),我们来通过这个用户名获取用户信息,以供validateCredentials(Authenticatable $user, array $credentials);来进行用户的验证。

    我们看到我们都需要返回一个Authenticatable $user的东西。 这个接口要求我们去实现很多user model的功能,比如获取密码之类。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php

    namespace Illuminate\Contracts\Auth;

    interface Authenticatable {

    public function getAuthIdentifierName();
    public function getAuthIdentifier();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();

    }

    自己统统去实现自然也是可以的,不过Laravel已经提供了一个叫GenericUser的类来帮助我们啦。我们直接把从API获取的用户信息来生成一个GenericUser的对象就行了。

    想这样。 当然由于GenericUser需要有些特殊的attribute,所以当没有的时候我们可以找适当的项目不上。比如下面的例子,我们需要提供一个name的attribute。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public function validateCredentials(\Illuminate\Contracts\Auth\Authenticatable $user, array $credentials)
    {
    // we'll assume if a user was retrieved, it's good
    $attributes = $this->client->Auth(['username' => $credentials["username"], 'passwd'=>$credentials["password"]]);
    if($attributes["status"] != 1)
    {
    return null;
    }
    else
    {
    $attributes["data"]["name"] = $attributes["data"]["firstname"].$attributes["data"]["lastname"];
    return new GenericUser($attributes["data"]);
    }
    }

    具体实现就不贴了,由于API本身不是很优雅,上层实现也不是那么优雅就是了。

    如果你觉得本文对你有帮助,请给我点赞助。