2015-10-25 4 views
6

Beschreibung:Angepasste Benutzerauthentifizierung Basis auf der Antwort eines API-Aufruf

Ich habe jetzt ein Bündel von Projekt Laravel im Einsatz. Die Implementierung der Benutzerauthentifizierung ist in Laravel einfach. Nun, die Struktur, mit der ich es zu tun habe, ist etwas anders - ich habe keine database oder users Tabelle lokal. Ich muss einen API-Aufruf machen, um abzufragen, was ich brauche.


habe ich versucht,

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); 
    } 
    } 

Aktualisiert

ich an die API verbinden in meiner VSE Klasse einen einfachen shell_exec Befehl

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]; 
    } 

Ich wünschte, ich kann Ihnen das hier zeigen, aber es ist auf der VM auf meinem lokalen Computer, also bitte bleiben Sie hier bei mir. Im Grunde ist es

Execute

curl http://172.16.67.137:1234/vse/accounts < --- aktualisiert

Antwort

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 

Wie Sie das Passwort für Bob sehen kann, ist abc und für Tom ist abd

+0

Sie können [das Laravel-Authentifizierungssystem erweitern] (http://laravel.com/docs/5.1/authentication#adding-custom-authentication-drivers), indem Sie einen eigenen Benutzerprovider erstellen, der die Anmeldebestätigung und Benutzerdetails verarbeitet. und das als Auth-Treiber einstellen. – Bogdan

+0

Wenn Sie feststellen, dass die Dokumentation nicht detailliert genug ist, dann können Sie sich die [Illuminate \ Auth \ DatabaseUserProvider'] (https://github.com/laravel/framework/blob/5.1/src/Illuminate/ Auth/DatabaseUserProvider.php) Quelle, um zu sehen, wie sie einen Datenbankbenutzer behandelt und die Logik auf Ihre Remote-API anwendet. – Bogdan

+0

Wenn Sie Code bereitstellen würden, der zeigt, wie Sie eine Verbindung mit der API herstellen und welche Anforderungen Sie zum Authentifizieren und Abrufen der Benutzerinformationen stellen, könnte ich wahrscheinlich eine Antwort geben, wie die API-Aufrufe in Laravel integriert werden Auth-Treiber – Bogdan

Antwort

8

anhand der folgenden Schritte können Sie Ihre eigenen Authentifizierungstreiber-Setup, die die Benutzer-Credentials mit Ihrem API-Aufruf übernimmt das Abrufen und Validierung:

1. Erstellen Sie Ihre eigenen Benutzer-Provider in app/Auth/ApiUserProvider.php mit folgendem Inhalt :

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. auch eine Benutzerklasse erzeugen, die GenericUser angeboten von dem Authentifizierungssystem in app/Auth/ApiUser.php mit dem Anschluss an dem Standard erstreckt Inhalt:

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. In Ihrem app/Providers/AuthServiceProvider.php Boot-Methode der Datei, registrieren Sie den neuen Treiber Benutzer Anbieter:

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. schließlich in Ihrer config/auth.php-Datei festgelegt, den Treiber zu Ihrer benutzerdefinierten ein:

'driver' => 'api', 

Sie jetzt die folgenden in Ihrem Controller-Aktion zu tun:

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); 
    } 
} 

aufrufen Auth::user() Benutzerdaten nach einer erhalten Erfolgreiche Anmeldung, gibt eine ApiUser Instanz zurück, die die Attribute enthält, die von der Remote-API abgerufen wurden und würde in etwa so aussehen:

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

Da Sie nicht eine Probe der Antwort geschrieben haben, dass Sie erhalten, wenn es in der API für den Benutzer E-Mail kein Spiel ist, ich Setup die Bedingung in der getUserDetails Methode, um festzustellen, dass es keine Übereinstimmung gibt und zurück null wenn Die Antwort enthält keine data Eigenschaft oder wenn die data Eigenschaft leer ist. Sie können diese Bedingung nach Ihren Bedürfnissen ändern.

Der obige Code wurde mit einer mokierten Antwort getestet, die die Datenstruktur zurückgibt, die Sie in Ihrer Frage geschrieben haben, und sie funktioniert sehr gut.

Als letzte Anmerkung: sollten Sie dringend die API ändern, um die Benutzerauthentifizierung eher früher als später zu handhaben (vielleicht mithilfe einer Oauth-Implementierung), weil das Kennwort gesendet wurde (und noch beunruhigender als einfacher Text) ist nicht etwas, was du aufschieben willst.

+0

Ich merke nur, dass ich mit der falschen URL verbinden. Ich nehme an, stattdessen eine Anfrage an "/ vse/accounts" zu stellen. Ich hoffe, es macht Ihnen nichts aus, Ihre Antwort auf "Schritt 1" zu optimieren. Das tut mir leid. Ich korrigiere es einfach selbst, aber es bricht. Dies ist das erste Mal, ich habe es mit Fahrer zu tun. – ihue

+0

Also sollte es "/ vse/accounts/user /" sein. $ Benutzername'? – Bogdan

+0

'$ username' ist nicht mehr Teil der Regel. Nur '/ vse/accounts' und das war's. – ihue

Verwandte Themen