Tempo Di Valse

[PHP/Laravel] Auth::attempt 가 안될 때... 본문

개발/Web

[PHP/Laravel] Auth::attempt 가 안될 때...

TempoDiValse 2022. 7. 11. 16:56

사용자 로그인 및 인증 프로세스를 구현하려 이것저것 Laravel 문서를 보면서 잘 따라하고 있었다.

 

라라벨 8.x - 인증

라라벨 한글 메뉴얼 8.x - 인증

laravel.kr

인증에 대한 처리를 Laravel 에서는 아주 멋있게 구현을 해주었기 때문에 개발자는 조금의 코딩만 덧붙여서 애플리케이션을 완성 할 수 있도록 만들어 주었다.

 

그래서 찬찬히 보고 있었는데, 이메일 데이터와 비밀번호를 입력한 후에 Auth::attempt 를 사용하는 부분에서, 분명히 데이터는 있는데 계속 false 가 떨어져서 진행을 할 수가 없었다.

 

문서에 충실하게 작성한 코드는 다음과 같다.

// Controller

function authenticate(Request $request){
    $credentials = $request->validate([
        'email' => [ 'required', 'email' ],
        'password' => [ 'required' ]
    ]);

    $email = $credentials['email'];
    $password = $credentials['password'];

    if(Auth::attempt([
        "email" => $email,
        "password" => $password
    ])){
        echo "인증됨<br>";
    }
        
    echo "끝";
}

그리고 테스트 환경이기 때문에 Seeder 를 통해서 테스트 계정도 만들었다.

// Seeder

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // \App\Models\User::factory(10)->create();

        \App\Models\User::factory()->create([
            'name' => 'Test User',
            'email' => 'test@example.com',
            'password' => 'a'
        ]);
    }
}

 

폼도 만들었고, 이메일과 비밀번호에는 test@example.com 과 비밀번호는 'a' 를 입력했다. 그러나..

나와야 되는 결과인 "인증됨" 은 나오지 않고, "끝" 만 나오는 것이다. 그저 필요한 값만 전달해주면 되는 거지 않나 싶었지만 쉽게 허락하지는 않았다.

 

그래서 이래저래 구글링으로 찾아봤는데 Auth::attempt 를 사용하려면 패스워드 값을 Hash 처리해야 한다고 나와있는 것이다. 소스들을 조금씩 다시 바꿔보았다.

// Controller

function authenticate(Request $request){
    $credentials = $request->validate([
        'email' => [ 'required', 'email' ],
        'password' => [ 'required' ]
    ]);

    $email = $credentials['email'];
    $password = Hash::make($credentials['password']);

    if(Auth::attempt([
        "email" => $email,
        "password" => $password
    ])){
        echo "인증됨<br>";
    }
        
    echo "끝";
}

일단 컨트롤러에는 Hash 값을 전달할 수 있도록 변경을 했다. 그렇다면, Seeder 로 부터 들어가는 패스워드도 똑같이 Hash 처리를 할 필요가 있겠다 싶어서 변경했다. (어쨌든 비밀번호가 DB 내에 그대로 들어가는 일은 거의 없으니...)

// Seeder

use Illuminate\Support\Facades\Hash;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // \App\Models\User::factory(10)->create();

        \App\Models\User::factory()->create([
            'name' => 'Test User',
            'email' => 'test@example.com',
            'password' => Hash::make('a')
        ]);
    }
}

그렇게 돌려봤더니, 

 

안된다...

 

분명히 Hash 다 적용하고 잘 보내주었다. 혹시 Hash 값이 다른가 싶어서 Hash 파사드에 검증하는 메소드를 통해서 확인했는데 올바른 Hash 가 발급 되어있었다.

 

그래서 다시 구글링을 찾아보았다. 이번에는 User 객체를 수정하면 될 것이다 라는 글을 봤고, 한번 적용해보았다. \App\Model\User 객체에 다음 내용이 담긴 메소드를 추가했다.

namespace App\Models;

class User {
    // ...Codes

    public function setPasswordAttribute($value){
        $this->attributes['password'] = Hash::make($value);
    }
}

Auto Complete 로 제공해주는 메소드는 아니지만, Eloquent 의 Mutator 라는 기능을 사용한 것으로 User 테이블의 password 컬럼에 값을 삽입하게 되면 어떻게 해야된다 라는 것을 정의해 준다. 값이 삽입될 때 Hash 처리를 하도록 변경했기 때문에 Seeder 도 그에 맞게 다시 변경을 해준다.

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // \App\Models\User::factory(10)->create();

        \App\Models\User::factory()->create([
            'name' => 'Test User',
            'email' => 'test@example.com',
            'password' => 'a',
        ]);
    }
}

패스워드에 있던 Hash::make 를 삭제하고 plain text 만 집어넣었다

// Controller

function authenticate(Request $request){
    $credentials = $request->validate([
        'email' => [ 'required', 'email' ],
        'password' => [ 'required' ]
    ]);

    if(Auth::attempt([
        "email" => $credentials['email'],
        "password" => $credentials['password']
    ])){
        echo "인증됨<br>";
    }
        
    echo "끝";
}

그래서 다시 로그인을 실행했다.

완성~

반응형
Comments