Пользовательская база аутентификации пользователя в ответ на вызов API

описание:

теперь я использую Laravel для кучки проектов. Реализация аутентификации пользователя проста в Laravel. Теперь структура, с которой я имею дело, немного отличается - у меня нет database или users таблицы локально. Я должен сделать вызов API, чтобы запросить то, что мне нужно.


Я пробовал

public function postSignIn(){

    $username     = strtolower(Input::get('username'));
    $password_api = VSE::user('password',$username); // abc <-----
    $password     = Input::get('password'); // abc <-----


    if ( $password == $password_api ) {
        //Log user in
        $auth = Auth::attempt(); // Stuck here <----
    }

    if ($auth) {
      return Redirect::to('/dashboard')->with('success', 'Hi '. $username .' ! You have been successfully logged in.');
    }
    else {
      return Redirect::to('/')->with('error', 'Username/Password Wrong')->withInput(Request::except('password'))->with('username', $username);
    }
  }

Обновлено

подключиться к API с помощью простого в своем VSE класс

public static function user($attr, $username) {

        $data = shell_exec('curl '.env('API_HOST').'vse/accounts');
        $raw = json_decode($data,true);
        $array =  $raw['data'];
        return $array[$attr];
    }

Я хотел бы показать вам это здесь, но это на виртуальной машине на моей локальной машине, поэтому, пожалуйста, оставайтесь со мной здесь. В Принципе, Это

выполнить

curl http://172.16.67.137:1234/vse/accounts

ответ

Object
data:Array[2]

0:Object
DBA:""
account_id:111
account_type:"admin"
address1:"111 Park Ave"
address2:"Floor 4"
address3:"Suite 4011"
city:"New York"
customer_type:2
display_name:"BobJ"
email_address:"[email protected]"
first_name:"Bob"
last_name:"Jones"
last_updated_utc_in_secs:200200300
middle_names:"X."
name_prefix:"Mr"
name_suffix:"Jr."
nation_code:"USA"
non_person_name:false
password:"abc"
phone1:"212-555-1212"
phone2:""
phone3:""
postal_code:"10022"
state:"NY"
time_zone_offset_from_utc:-5

1:Object
DBA:""
account_id:112
account_type:"mbn"
address1:"112 Park Ave"
address2:"Floor 3"
address3:"Suite 3011"
city:"New York"
customer_type:2
display_name:"TomS"
email_address:"[email protected]"
first_name:"Tom"
last_name:"Smith"
last_updated_utc_in_secs:200200300
middle_names:"Z."
name_prefix:"Mr"
name_suffix:"Sr."
nation_code:"USA"
non_person_name:false
password:"abd"
phone1:"212-555-2323"
phone2:""
phone3:""
postal_code:"10022"
state:"NY"
time_zone_offset_from_utc:-5
message:"Success"
status:200

как вы можете видеть пароль для Боб abc и на том abd

1 ответов


следуя инструкциям ниже, вы можете настроить свой собственный драйвер аутентификации, который обрабатывает извлечение и проверку учетных данных Пользователя с помощью вызова API:

1. создайте свой собственный пользовательский провайдер в app/Auth/ApiUserProvider.php следующего содержания:

namespace App\Auth;

use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;

class ApiUserProvider implements UserProvider
{
    /**
     * Retrieve a user by the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByCredentials(array $credentials)
    {
        $user = $this->getUserByUsername($credentials['username']);

        return $this->getApiUser($user);
    }

    /**
     * Retrieve a user by their unique identifier.
     *
     * @param  mixed  $identifier
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveById($identifier)
    {
        $user = $this->getUserById($identifier);

        return $this->getApiUser($user);
    }

    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials)
    {
        return $user->getAuthPassword() == $credentials['password'];
    }

    /**
     * Get the api user.
     *
     * @param  mixed  $user
     * @return \App\Auth\ApiUser|null
     */
    protected function getApiUser($user)
    {
        if ($user !== null) {
            return new ApiUser($user);
        }
    }

    /**
     * Get the use details from your API.
     *
     * @param  string  $username
     * @return array|null
     */
    protected function getUsers()
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_URL, env('API_HOST') . 'vse/accounts');

        $response = curl_exec($ch);
        $response = json_decode($response, true);

        curl_close($ch);

        return $response['data'];
    }

    protected function getUserById($id)
    {
        $user = [];

        foreach ($this->getUsers() as $item) {
            if ($item['account_id'] == $id) {
                $user = $item;

                break;
            }
        }

        return $user ?: null;
    }

    protected function getUserByUsername($username)
    {
        $user = [];

        foreach ($this->getUsers() as $item) {
            if ($item['email_address'] == $username) {
                $user = $item;

                break;
            }
        }

        return $user ?: null;
    }

    // The methods below need to be defined because of the Authenticatable contract
    // but need no implementation for 'Auth::attempt' to work and can be implemented
    // if you need their functionality
    public function retrieveByToken($identifier, $token) { }
    public function updateRememberToken(UserContract $user, $token) { }
}

2. также создайте класс пользователя, который расширяет значение по умолчанию GenericUser предлагается системой аутентификации в app/Auth/ApiUser.php со следующими содержание:

namespace App\Auth;

use Illuminate\Auth\GenericUser;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;

class ApiUser extends GenericUser implements UserContract
{
    public function getAuthIdentifier()
    {
        return $this->attributes['account_id'];
    }
}

3. в своем app/Providers/AuthServiceProvider.php метод загрузки файла, зарегистрируйте нового поставщика пользователя драйвера:

public function boot(GateContract $gate)
{
    $this->registerPolicies($gate);

    // The code below sets up the 'api' driver
    $this->app['auth']->extend('api', function() {
        return new \App\Auth\ApiUserProvider();
    });
}

4. наконец-то в свой config/auth.php файл установите драйвер на свой пользовательский:

    'driver' => 'api',

теперь вы можете сделать следующее в своем действии контроллера:

public function postSignIn()
{
    $username = strtolower(Input::get('username'));
    $password = Input::get('password');

    if (Auth::attempt(['username' => $username, 'password' => $password])) {
        return Redirect::to('/dashboard')->with('success', 'Hi '. $username .'! You have been successfully logged in.');
    } else {
        return Redirect::to('/')->with('error', 'Username/Password Wrong')->withInput(Request::except('password'))->with('username', $username);
    }
}

вызов Auth::user() чтобы получить данные пользователя после успешного входа в систему, вернет ApiUser экземпляра, содержащего атрибуты, извлеченные из удаленного API, будут выглядеть примерно так:

ApiUser {#143 ▼
  #attributes: array:10 [▼
    "DBA" => ""
    "account_id" => 111
    "account_type" => "admin"
    "display_name" => "BobJ"
    "email_address" => "[email protected]m"
    "first_name" => "Bob"
    "last_name" => "Jones"
    "password" => "abc"
    "message" => "Success"
    "status" => 200
  ]
}

поскольку вы не опубликовали образец ответа, который вы получаете, когда в API нет соответствия для электронной почты пользователя, я устанавливаю условие в getUserDetails метод, чтобы определить, что нет совпадения и возврата null если ответ не содержит data свойство или если data свойство является пустым. Вы можете изменить это условие согласно вашему по необходимости.


приведенный выше код был протестирован с использованием насмешливого ответа, который возвращает структуру данных, опубликованную в вашем вопросе, и она работает очень хорошо.

в качестве заключительного Примечания: вы должны настоятельно рассмотреть возможность изменения API для обработки аутентификации пользователя раньше, чем позже (возможно, с помощью реализации Oauth), потому что отправка пароля (и даже более тревожно, как обычный текст) - это не то, что вы хотите отложить делающий.