이전 포스팅 에서 데이터를 가져왔으니, 로그인을 구현해보자.
Basic Auth
라라벨에서 제공하는 회원가입, 로그인, 비밀번호 찾기 기능을 사용하고 싶다면 artisan 명령어로 간단하게 시작할 수 있다.
명령어를 실행하면 resources/views/auth 폴더에 뷰가 app/Http/Controllers/Auth 에 로직이 생성되고 routes/web.php 에 라우팅이 등록된다.
DB도 같이 만들고 싶다면 Docs 를 따라하자.
다른 테이블 사용
제공된 user 테이블을 안 쓰려면 커스터마이징이 필요하다.
설정 변경
config/auth.php 파일로 이동해 다른 모델을 등록하자.
config/auth.php
<?php 'providers' => [ 'users' => [ 'driver' => 'eloquent' , 'model' => App \ Models \ Member :: class , ] ]
config 안의 파일을 변경하면 config:clear를 실행해 혹시 모를 캐시를 날려주자
그리고 app/Models/Member.php 로 이동해 내 모델을 라라벨 기본 인증 모듈을 사용할 수 있게 추가해야한다.
app/Models/Member.php
<? use Illuminate \ Foundation \ Auth \ User as Authenticatable ; use Illuminate \ Notifications \ Notifiable ; class Member extends Authenticatable { use Notifiable ; protected $guarded = [ 'member_id' , 'remember_token' ] ; protected $hidden = [ 'password' , 'remember_token' , ] ; }
인증 필드 변경
Basic Auth는 기본 필드를 email로 잡고 있기 때문에 id 필드를 사용하게 변경해야한다.
app/Http/Controllers/Auth/LoginController.php
<?php public function username ( ) { return 'id' ; }
회원가입 후 자동로그인
회원가입이 성공하면 세션을 생성해줘야한다.
app/Http/Controllers/Auth/RegisterController.php
<?php protected function registered ( Request $request , $user ) { Auth :: attempt ( [ 'id' => $request -> input ( 'id' ) , 'password' => $request -> input ( 'password' ) ] ) ; return response ( null , 204 ) ; }
ajax 처리
로그인
로그인을 ajax로 처리해야될 경우 커스터마이징이 필요하다.
app/Http/Controllers/Auth/LoginController.php
<?php protected function authenticated ( Request $request , $user ) { if ( $request -> ajax ( ) ) { return response ( ) -> json ( [ 'href' => url ( ) -> previous ( ) ] ) ; } else { return abort ( 405 ) ; } }
비밀번호 찾기
비밀번호 찾기를 ajax로 처리해야될 경우 커스터마이징이 필요하다.
app/Http/Controllers/Auth/ForgotPasswordController.php
<?php public function sendResetLinkEmail ( Request $request ) { $this -> validateId ( $request ) ; $data = Member :: where ( 'id' , $request -> only ( 'id' ) ) -> first ( [ 'email' ] ) ; $email = isset ( $data -> email ) ? $data -> email : null ; $response = $this -> broker ( ) -> sendResetLink ( [ 'email' => $email ] ) ; return response ( ) -> json ( [ 'email' => $email ] , $response == Password :: RESET_LINK_SENT ? 200 : 500 ) ; }
routing 예외
ajax 요청으로 바꿨다면 굳이 필요없는 기본 route는 등록할 필요가 없다. (예를 들면 로그인 페이지)
먼저 routes/web.php 에서 Auth::routes();
를 지워주고 라라벨 route 파일을 열어보자.
vendor/laravel/Illuminate/Routing/Router.php
public function auth ( ) { $this -> get ( 'login' , 'Auth\LoginController@showLoginForm' ) -> name ( 'login' ) ; $this -> post ( 'login' , 'Auth\LoginController@login' ) ; $this -> post ( 'logout' , 'Auth\LoginController@logout' ) -> name ( 'logout' ) ; $this -> get ( 'register' , 'Auth\RegisterController@showRegistrationForm' ) -> name ( 'register' ) ; $this -> post ( 'register' , 'Auth\RegisterController@register' ) ; $this -> get ( 'password/reset' , 'Auth\ForgotPasswordController@showLinkRequestForm' ) -> name ( 'password.request' ) ; $this -> post ( 'password/email' , 'Auth\ForgotPasswordController@sendResetLinkEmail' ) -> name ( 'password.email' ) ; $this -> get ( 'password/reset/{token}' , 'Auth\ResetPasswordController@showResetForm' ) -> name ( 'password.reset' ) ; $this -> post ( 'password/reset' , 'Auth\ResetPasswordController@reset' ) ; }
입맛에 맞게 web.php로 가져와 사용하자.
notification 예외
Noticifation은 사용자에게 빠르게 알림을 보낼 수 있는 기능이지만, 정해져 있는 템플릿을 사용하므로 커스터마이징이 되게 힘들다.
비밀번호 찾기시에 보낼 메일을 정해진 템플릿을 사용할 수 없다면 메소드를 수정하자.
app/Models/Member.php
<?php public function sendPasswordResetNotification ( $token ) { Mail :: to ( $this -> email ) -> send ( new PasswordReset ( $token ) ) ; }
Auth
Basic Auth를 사용하는데 건드려야 되는 곳이 많으므로 Auth 모듈만 사용하는게 정신건강에 좋다고 본다.
(Bootstrap 기반의 Laravel에 딱 맞는 모양을 입은 프로젝트라면 기본 인증이 좋겠지만)
로그인
먼저 사용할 모델에 Authenticatable 클래스를 상속 받자
그리고 LoginController에서 Auth::attempt() 메소드를 실행하면 끝이다.
app/Http/Controllers/LoginController.php
public function login ( Request $request ) { $password = $request -> password ; if ( Auth :: attempt ( [ 'id' => $request -> id , 'password' => $password ] ) ) { return response ( null , 200 ) ; } else { return abort ( 401 ) ; } }
not bcrypt
Auth 모듈은 기본으로 bcrypt를 사용해 비밀번호를 암호화하고 비교하는데 다른 암호화 방식을 사용해야하는 경우가 있다.
bcrypt를 사용하지 않게 처리해보자.
app/Models/Member.php
public function getAuthPassword ( ) { return Hash :: make ( $this -> password ) ; }
이제 Auth::attempt() 메소드에 패스워드를 넘길 때 암호화를 해주고 넘기면 된다.
N개의 세션
관리자와 회원은 같은 세션을 사용하면 안 된다. 세션을 분기해보자.
모델 생성
먼저 모델을 하나 만들고 Authenticatable 클래스를 상속받는다.
app/Models/Admin.php
<?php use Illuminate \ Foundation \ Auth \ User as Authenticatable ; class Admin extends Authenticatable { }