如何创建Laravel 5.1 Custom Authentication驱动程序?

时间:2015-08-27 07:38:03

标签: php laravel laravel-5 laravel-5.1

我正在使用社交网站进行Laravel身份验证登录。现在我可以从社交网站保存用户数据了。但现在我面临着如何从gmail,github验证用户的问题。

经过一些研究后,我了解到我需要创建自定义身份验证。我用Google搜索,但都是Laravel 4.1主题。如果有人就此工作,请提供您的答案。

我已经阅读了以下主题,但我还没有做到这一点?

http://laravel.com/docs/5.1/authentication#social-authentication

http://laravel.com/docs/5.1/providers

http://laravel-recipes.com/recipes/115/using-your-own-authentication-driver

http://laravel.io/forum/11-04-2014-laravel-5-how-do-i-create-a-custom-auth-in-laravel-5

更新

public function handleProviderCallback() {
    $user = Socialite::with('github')->user();
    $email=$user->email;
    $user_id=$user->id;

    //$authUser = User::where('user_id',$user_id)->where('email', $email)->first();
    $authUser = $this->findOrCreateUser($user);

    if(Auth::login($authUser, true)) {
        return Redirect::to('user/UserDashboard');
    }   
}

private function findOrCreateUser($user) {
    if ($authUser = User::where('user_id',$user->id)->first()) {
        return $authUser;
    }

    return User::create([
        'user_id' => $user->id,
        'name' => $user->nickname,
        'email' => $user->email,
        'avatar' => $user->avatar
    ]);
}

1 个答案:

答案 0 :(得分:16)

  

这个答案最适合Laravel 5.1。如果你,请小心   在其他一些版本中。还要记住,恕我直言,这是Laravel的一个相当高级的水平,因此如果你不完全了解你在做什么,你可能最终崩溃你的应用程序。解决方案不是端到端正确的。这只是您需要做什么才能使其发挥作用的一般准则。

在Laravel 5.1中添加自定义身份验证驱动程序

提示:此主题的Laravel文档为here

提示2:您提到的最后一个链接在我看来非常有用。阅读完该链接后,我学会了所有这些。

http://laravel.io/forum/11-04-2014-laravel-5-how-do-i-create-a-custom-auth-in-laravel-5

在开始之前,我首先想描述一下登录流程,它将帮助您理解该过程。 Laravel使用driver连接到数据库以获取记录。两名司机预先捆绑了laravel - eloquent& database。我们想要创建第三个,以便我们可以根据我们的需求进行定制。

供应商文件夹中的

Illuminate\Auth\Guard是主文件,其中包含用户登录和注销的代码。此文件主要使用我们需要覆盖的两个Contracts (or interfaces),以便我们的驱动程序工作。从Laravel自己的文档中读取:

  

只有Illuminate \ Contracts \ Auth \ UserProvider实现   负责获取Illuminate \ Contracts \ Auth \ Authenticatable   从持久性存储系统(如MySQL)中实现   Riak等。这两个接口允许Laravel身份验证   无论用户数据如何,都可以继续运行   存储或使用什么类型的类来表示它。

所以我的想法是,为了让我们的驱动程序工作,我们需要实现Illuminate\Contracts\Auth\UserProviderIlluminate\Contracts\Auth\Authenticatable并告诉Laravel使用这些实现而不是默认值。

让我们开始吧。

<强> Step 1: 选择驱动程序的名称。我将我的名字命名为socialite。然后在config/auth.php中,将driver名称更改为socialite。通过这样做,我们告诉laravel使用此驱动程序进行身份验证,而不是默认的eloquent

<强> Step 2: app/Provider/AuthServiceProvider方法的boot()中添加以下行:

Auth::extend('socialite', function($app) {
    $provider = new SocialiteUserProvider();
    return new AuthService($provider, App::make('session.store'));
});

我们在这里做的是:

  • 我们首先使用Auth外观来定义socialite驱动程序。
  • SocialiteUserProviderUserProvider
  • 的实现
  • AuthService是我Guard课程的延伸。这个类的构造函数采用的第二个参数是laravel用于获取和设置会话的会话。
  • 所以我们基本上告诉Laravel使用我们自己的Guard类实现而不是默认类。

<强> Step 3: 创建SocialiteUserProvider。如果您阅读Laravel的文档,您将了解每种方法应返回的内容。我已经创建了第一个方法作为样本。如您所见,我使用UserService类来获取结果。您可以获取自己的结果,但想要获取它们。然后我从中创建了一个User对象。此User类实现Illuminate\Contracts\Auth\Authenticatable合同。

<?php
namespace App\Extensions;

use App\User;
use App\Services\UserService;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;

class SocialiteUserProvider implements UserProvider
{
    private $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    public function retrieveById($identifier)
    {
        $result = $this->userService->getUserByEmail($identifier);
        if(count($result) === 0)
        {
            $user = null;
        }
        else
        {
            $user = new User($result[0]);
        }

        return $user;
    }

    public function retrieveByToken($identifier, $token)
    {
        // Implement your own.
    }

    public function updateRememberToken(Authenticatable $user, $token)
    {
        // Implement your own.
    }

    public function retrieveByCredentials(array $credentials)
    {
        // Implement your own.
    }

    public function validateCredentials(Authenticatable $user, array $credentials)
    {
        // Implement your own.
    }
}

<强> Step 4: 创建实现User的{​​{1}}类。该类必须实现此接口,因为Authenticatable类将使用此类来获取值。

Guard

<强> <?php namespace App; use Illuminate\Contracts\Auth\Authenticatable; class User implements Authenticatable { protected $primaryKey = 'userEmail'; protected $attributes = []; public function __construct(array $attributes) { $this->attributes = $attributes; } public function getUserAttributes() { return $this->attributes; } public function getAuthIdentifier() { return $this->attributes[$this->primaryKey]; } public function getAuthPassword() { // Implement your own. } public function getRememberToken() { // Implement your own. } public function setRememberToken($value) { // Implement your own. } public function getRememberTokenName() { // Implement your own. } } 最后创建将调用Step 5:方法的AuthService类。这是我自己的实现。您可以根据自己的需要自行编写。我们在这里做的是扩展Guard类来实现两个自我解释的新函数。

Guard

<强> <?php namespace App\Services; use Illuminate\Auth\Guard; class AuthService extends Guard { public function signin($email) { $credentials = array('email' => $email); $this->fireAttemptEvent($credentials, false, true); $this->lastAttempted = $user = $this->provider->retrieveById($email); if($user !== null) { $this->login($user, false); return true; } else { return false; } } public function signout() { $this->clearUserDataFromStorage(); if(isset($this->events)) { $this->events->fire('auth.logout', [$this->user()]); } $this->user = null; $this->loggedOut = true; } } 为了完成我的回答,我还将解释Step 6: Bonus Step类期望的结构。首先让我们了解这个课程的作用。在上面的步骤中,我们创建了所有内容,让laravel知道如何使用我们的身份验证驱动程序,而不是他们的。但我们仍然没有告诉laravel应该如何获取数据。我们告诉laravel,如果你调用UserService方法,你将得到你的数据。所以现在我们只需要实现这个功能。

E.g.1您正在使用userService->getUserByEmail($email)

Eloquent

例如,您使用的是public function getUserByEmail($email) { return UserModel::where('email', $email)->get(); }

Fluent

更新:2016年6月19日

感谢@skittles指出我没有清楚地显示应放置文件的位置。所有文件都按照给定的命名空间放置。例如。如果名称空间为public function getUserByEmail($email) { return DB::table('myusertable')->where('email', '=', $email)->get(); } 且类名为App\Extensions,则文件位置为SocialiteUserProvider。 laravel中的App\Extensions\SocialiteUserProvider.php目录是App文件夹。