Skip to content
This repository has been archived by the owner on Dec 23, 2020. It is now read-only.

Trouble using LdapRecord + Passport + Laravel + API #17

Open
merlinnusr opened this issue Dec 21, 2020 · 1 comment
Open

Trouble using LdapRecord + Passport + Laravel + API #17

merlinnusr opened this issue Dec 21, 2020 · 1 comment

Comments

@merlinnusr
Copy link

ok, I'm trying to create a simple API with authetication with a LDAP server ldap.forumsys.com this is a test ldap server but I get this error

BadMethodCallException with message 'Method Illuminate\Auth\RequestGuard::attempt does not exist.'

I'm not sure if this is an passport error or a ldaprecord error.

I check my connection and its correct

docker exec -it api php artisan ldap:test
Testing LDAP connection [default]...
+------------+------------+----------+-------------------------+---------------+
| Connection | Successful | Username | Message                 | Response Time |
+------------+------------+----------+-------------------------+---------------+
| default    | ✔ Yes      |          | Successfully connected. | 271.31ms      |
+------------+------------+----------+-------------------------+---------------+

.env file

LDAP_LOGGING=true
LDAP_CONNECTION=default
LDAP_HOST=ldap.forumsys.com
LDAP_USERNAME=null
LDAP_PASSWORD=null
LDAP_PORT=389
LDAP_BASE_DN="DC=example,DC=com"
LDAP_TIMEOUT=5
LDAP_SSL=false
LDAP_TLS=false

config/auth.php

return [
    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
            'hash' => false,
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'ldap',
            'hash' => false,
        ],
    ],
    'providers' => [
        'ldap' => [
            'driver' => 'ldap',
            'model' => LdapRecord\Models\ActiveDirectory\User::class,
            'database' => [
                'model' => App\Models\User::class,
                'sync_passwords' => false,
                'sync_attributes' => [
                    'name' => 'cn',
                    'email' => 'mail',
                ],
            ],
        ],
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

    ],
]

App\Models\User I alredy implemented LdapRecord\Laravel\Auth\LdapAuthenticatable; and LdapRecord\Laravel\Auth\AuthenticatesWithLdap; as documentation says

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes; //línea necesaria
use App\Http\Traits\LogTrait;
use Spatie\Permission\Traits\HasRoles;
use Laravel\Passport\HasApiTokens;
use LdapRecord\Models\Model;
use LdapRecord\Laravel\Auth\LdapAuthenticatable;
use LdapRecord\Laravel\Auth\AuthenticatesWithLdap;
class User extends Authenticatable implements LdapAuthenticatable
{
    use HasFactory, Notifiable, 
    SoftDeletes,LogTrait,
    Authenticatable,HasRoles, HasApiTokens, 
    AuthenticatesWithLdap;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'username',
        'email',
        'password',
        'modules',
        'bearer_token',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    protected $dates = ['deleted_at'];

    public function employee()
    {
        return $this->hasOne('App\Models\Employee');
    }
    public function ticket_historics()
    {
        return $this->hasMany('App\Models\TicketHistoric');
    }
    public function department()
    {
        return $this->hasOne('App\Models\Department');
    }
}

So when I try to authenticate with a User I get this error. Is this a right way to use ldap in API mode?

Auth::attempt(['email' => 'tesla', 'password' => 'password'])
BadMethodCallException with message 'Method Illuminate\Auth\RequestGuard::attempt does not exist.'
@stevebauman
Copy link
Member

stevebauman commented Dec 21, 2020

Hi @merlinnusr,

If you're attempting to create a simple API, I would heavily suggest moving to Laravel Sanctum instead of using Laravel Passport. Laravel Passport requires a decent understanding of OAuth2, along with some heavy setup and configuration.

Here's a step-by-step guide for getting up and running with Laravel Sanctum:

https://laravel.com/docs/8.x/sanctum#spa-authentication

To answer to your specific issue -- Laravel Passport does not use credentials to authenticate users. It uses tokens. Therefore it does not have the attempt() method as the exception describes.

https://laracasts.com/discuss/channels/laravel/method-illuminateauthrequestguardattempt-does-not-exist#best-reply-559749

You must first issue a token (which creates a token inside of your database owned by the user), then provide that token alongside requests to your protected application routes. This is how Laravel Passport "authenticates" requests made to protected routes -- not by providing user credentials.

Laravel Sanctum allows you to use session cookies alongside tokens -- making it a great choice on building an API.

Hope this helps! 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants