Udemy - Nuxt JS with Laravel API - Building SSR Vue JS Apps 笔记10 Laravel - API Authentication

Setup Laravel JWT Authentication

https://jwt-auth.readthedocs.io/en/docs/laravel-installation/

https://appdividend.com/2018/02/24/laravel-jwt-authentication-tutorial/

https://blog.pusher.com/laravel-jwt/

切换到backend项目:参考 https://jwt-auth.readthedocs.io/en/docs/laravel-installation/ 执行:

composer require tymon/jwt-auth

执行:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

参考 https://jwt-auth.readthedocs.io/en/develop/quick-start/ 更新User模型:

User.php

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

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

    /**
     * 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',
    ];

    // Rest omitted for brevity
    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

参考 https://jwt-auth.readthedocs.io/en/develop/quick-start/ Configure Auth guard 修改config/auth.php文件:

批注 2020-05-14 215851

批注 2020-05-14 220005

Register User

api.php:

<?php

use \Illuminate\Support\Facades\Route;

Route::post('register', 'AuthController@register')->middleware('guest');

创建这个AuthController,执行:

php artisan make:controller AuthController

AuthController.php:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $data = $request->validate([
            'email' => 'string|email|required|unique:users,email',
            'name' => 'required|string|unique:users,name',
            'password' => 'required|min:6|max:255|confirmed',
        ]);

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

        $user = User::create($data);

        return $user;
    }
}

用PostMan测试结果:

批注 2020-05-15 004952

Create Validation Request

执行

php artisan make:request UserRegisterRequest
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserRegisterRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => 'string|email|required|unique:users,email',
            'name' => 'required|string|unique:users,name',
            'password' => 'required|min:6|max:255|confirmed',
        ];
    }
}

修改AuthController.php:

<?php

namespace App\Http\Controllers;

use App\Http\Requests\UserRegisterRequest;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(UserRegisterRequest $request)
    {
        $request['password'] = Hash::make($request['password']);

        $user = User::create($request->all());

        return $user;
    }
}

Laravel Api Resource

执行:

php artisan make:resource UserResource
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
        ];
//        return parent::toArray($request);
    }
}

修改AuthController.php:

<?php

namespace App\Http\Controllers;

use App\Http\Requests\UserRegisterRequest;
use App\Http\Resources\UserResource;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(UserRegisterRequest $request)
    {
        $request['password'] = Hash::make($request['password']);

        $user = User::create($request->all());

        return UserResource::make($user);
    }
}

PostMan测试结果:

批注 2020-05-15 010513

Respond With Token

修改AuthController.php:

<?php

namespace App\Http\Controllers;

use App\Http\Requests\UserRegisterRequest;
use App\Http\Resources\UserResource;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(UserRegisterRequest $request)
    {
        $request['password'] = Hash::make($request['password']);

        $user = User::create($request->all());

        if (!$token = auth()->login($user)) {
            return abort(401);
        }
        return UserResource::make($request->user())->additional(
            [
                'meta' => [
                    'token' => $token,
                ]
            ]
        );
    }
}

Postman测试:

批注 2020-05-15 012216

User Login

api.php修改如下:

<?php

use \Illuminate\Support\Facades\Route;

Route::post('register', 'AuthController@register')->middleware('guest');
Route::post('login', 'AuthController@login')->middleware('guest');

执行:

php artisan make:request UserLoginRequest
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserLoginRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => 'string|email|required',
            'password' => 'required|min:6|max:255',
        ];
    }
}

AuthController.php修改如下:

<?php

namespace App\Http\Controllers;

use App\Http\Requests\UserLoginRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Http\Resources\UserResource;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(UserRegisterRequest $request)
    {
        $request['password'] = Hash::make($request['password']);

        $user = User::create($request->all());

        if (!$token = auth()->login($user)) {
            return abort(401);
        }
        return UserResource::make($request->user())->additional(
            [
                'meta' => [
                    'token' => $token,
                ]
            ]
        );
    }

    public function login(UserLoginRequest $request)
    {
        if (!$token = auth()->attempt($request->only(['email', 'password']))) {
            return response()->json(['errors' => 'wrong credentials'],422);
        }

        return UserResource::make(auth()->user())->additional([
            'meta' => [
                'token' => $token,
            ]
        ]);
    }
}

PostMan测试结果:

批注 2020-05-15 013112

User EndPoint

api.php:

<?php

use \Illuminate\Support\Facades\Route;

Route::post('register', 'AuthController@register')->middleware('guest');
Route::post('login', 'AuthController@login')->middleware('guest');
Route::get('user', 'AuthController@user')->middleware('auth');

参考 https://stackoverflow.com/questions/53379271/jwt-authentication-error-argument-3-passed-to-lcobucci-jwt-signer-hmacdoverify 执行:

php artisan key:generate
php artisan jwt:secret
php artisan cache:clear
php artisan config:clear

修改AuthController.php

<?php

namespace App\Http\Controllers;

use App\Http\Requests\UserLoginRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Http\Resources\UserResource;
use App\User;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{

    public function register(UserRegisterRequest $request)
    {
        $request['password'] = Hash::make($request['password']);

        $user = User::create($request->all());

        if (!$token = auth()->login($user)) {
            return abort(401);
        }
        return UserResource::make($request->user())->additional(
            [
                'meta' => [
                    'token' => $token,
                ]
            ]
        );
    }

    public function login(UserLoginRequest $request)
    {
        if (!$token = auth()->attempt($request->only(['email', 'password']))) {
            return response()->json(['errors' => 'wrong credentials'], 422);
        }

        return UserResource::make(auth()->user())->additional([
            'meta' => [
                'token' => $token,
            ]
        ]);
    }

    public function user(Request $request)
    {
        return UserResource::make($request->user());
    }
}

PostMan发起请求:

批注 2020-05-15 021256

或者:

批注 2020-05-15 021323

User Logout

api.php:

<?php

use \Illuminate\Support\Facades\Route;

Route::post('register', 'AuthController@register')->middleware('guest');
Route::post('login', 'AuthController@login')->middleware('guest');
Route::get('user', 'AuthController@user')->middleware('auth');
Route::post('logout', 'AuthController@logout')->middleware('auth');

AuthController.php:

<?php

namespace App\Http\Controllers;

use App\Http\Requests\UserLoginRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Http\Resources\UserResource;
use App\User;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{

    public function register(UserRegisterRequest $request)
    {
        $request['password'] = Hash::make($request['password']);

        $user = User::create($request->all());

        if (!$token = auth()->login($user)) {
            return abort(401);
        }
        return UserResource::make($request->user())->additional(
            [
                'meta' => [
                    'token' => $token,
                ]
            ]
        );
    }

    public function login(UserLoginRequest $request)
    {
        if (!$token = auth()->attempt($request->only(['email', 'password']))) {
            return response()->json(['errors' => 'wrong credentials'], 422);
        }

        return UserResource::make(auth()->user())->additional([
            'meta' => [
                'token' => $token,
            ]
        ]);
    }

    public function user(Request $request)
    {
        return UserResource::make($request->user());
    }

    public function logout()
    {
        auth()->logout();
        return response()->json(['message' => 'logout successful!'], 201);
    }

}

Postman测试结果:

批注 2020-05-15 021842

Add CORS Support

使用Laravel CORS package

参考 CORS Middleware for Laravel 执行:

composer require fruitcake/laravel-cors

我这里执行的时候有错误:

批注 2020-05-15 022853

所以果断在composer.json里添加

"fruitcake/laravel-cors": "^1.0",

然后执行:

composer update

批注 2020-05-15 023028

然后配置

批注 2020-05-15 023232

配置path前执行:

php artisan vendor:publish --tag="cors"


批注 2020-05-15 023445

更多options参考 https://github.com/fruitcake/laravel-cors

一般就用默认就可以啦。

原教程中AuthController少了一个refresh逻辑,可以参考 https://jwt-auth.readthedocs.io/en/docs/quick-start/ 自己添加。

源代码:

https://github.com/dzkjz/laravel-backend-nuxt-frontend

批注 2020-05-15 023956

posted @ 2020-05-15 01:33  dzkjz  阅读(75)  评论(0)    收藏  举报