이 기사에서는 JWT 인증을 사용하여 Laravel에서 Restful API를 구축하는 방법을 알아봅니다. JWT는 JSON 웹 토큰을 나타냅니다. 또한 API를 사용하여 사용자 제품에 대한 완전한 기능의 CRUD 애플리케이션을 생성할 것입니다.
API는 크로스 플랫폼 애플리케이션을 사용할 때 매우 좋은 선택입니다. 귀하의 제품에는 웹사이트 외에도 Android 및 iOS 앱이 있을 수도 있습니다. 이 경우 백엔드 코드를 변경하지 않고도 다양한 프런트엔드를 작성할 수 있으므로 API도 마찬가지로 훌륭합니다. API를 사용할 때 일부 매개변수와 함께 GET, POST 또는 기타 유형의 요청을 누르면 서버는 클라이언트 애플리케이션에서 처리되는 JSON(JavaScript Object Notation) 형식으로 일부 데이터를 반환합니다.
설명
먼저 앱 세부 정보와 기능을 적어 보겠습니다. JWT 인증을 사용하여 laravel에서 Restful API를 사용하여 기본 사용자 제품 목록을 구축합니다.
A 사용자 는 다음 기능을 사용하여 등록하고 새 계정을 만듭니다.
계정에 로그인
로그아웃하고 토큰을 삭제하고 앱을 종료합니다
가져오기 로그인한 사용자의 세부 정보
사용자가 사용할 수 있는 제품 목록 검색
ID로 특정 제품 찾기
사용자 제품 목록에 새 제품 추가
기존 제품 세부 정보 편집
기존 제품 제거 사용자 목록
A 사용자 필수
이름
password
A 제품 필수
이름
가격
Quantity
아래 명령어를 실행하면 새로운 Laravel 프로젝트를 시작하고 생성할 수 있습니다.
composer create-project --prefer-dist laravel/laravel jwt
이렇게 하면 jwt라는 디렉터리에 새 Laravel 프로젝트가 생성됩니다.
JWT 확장 패키지 구성
Laravel에서 JWT를 사용할 수 있도록 tymondesigns/jwt-auth 확장 패키지를 사용하겠습니다.
tymon/jwt-auth 확장 패키지를 설치하세요
이 확장 패키지를 Laravel 애플리케이션에 설치해 보겠습니다. Laravel 5.5 이상을 사용하는 경우 다음 명령을 실행하여 JWT 패키지의 dev-develop 버전을 얻으세요:
composer require tymon/jwt-auth:dev-develop --prefer-source
Laravel 5.4 이하를 사용하는 경우 다음 명령을 실행하세요:
composer require tymon/jwt-auth
For Laravel For 5.5 이전 버전을 사용하는 애플리케이션의 경우 config/app.php 파일에서 서비스 공급자와 별칭도 설정해야 합니다.
'providers' => [ .... Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class, .... ], 'aliases' => [ .... 'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, 'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory', .... ],
Laravel 버전이 5.5 이상인 경우 Laravel은 "패키지 자동 검색"을 수행합니다.
구성 파일 게시
Laravel 5.5 이상의 버전에서는 다음 명령을 사용하여 구성 파일을 게시하세요.
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
이전 버전의 Laravel에서는 다음 명령을 실행해야 합니다:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
위 명령은 config/jwt.php 구성 파일을 생성합니다. 주석이 제거되면 구성 파일은 다음과 같습니다.
<?php return [ 'secret' => env('JWT_SECRET'), 'keys' => [ 'public' => env('JWT_PUBLIC_KEY'), 'private' => env('JWT_PRIVATE_KEY'), 'passphrase' => env('JWT_PASSPHRASE'), ], 'ttl' => env('JWT_TTL', 60), 'refresh_ttl' => env('JWT_REFRESH_TTL', 20160), 'algo' => env('JWT_ALGO', 'HS256'), 'required_claims' => [ 'iss', 'iat', 'exp', 'nbf', 'sub', 'jti', ], 'persistent_claims' => [ // 'foo', // 'bar', ], 'lock_subject' => true, 'leeway' => env('JWT_LEEWAY', 0), 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true), 'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0), 'decrypt_cookies' => false, 'providers' => [ 'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class, 'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class, 'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class, ], ];
Generate JWT Key
JWT 토큰은 암호화된 키를 통해 발급됩니다. Laravel 5.5 이상에서는 다음 명령을 실행하여 토큰 발급을 위한 키를 생성합니다.
php artisan jwt:secret
Laravel 5.5 미만 버전 실행:
php artisan jwt:generate
이 튜토리얼에서는 Laravel 5.6을 사용합니다. 튜토리얼의 다음 단계는 5.5 및 5.6에서만 테스트되었습니다. Laravel 5.4 이하에서는 작동하지 않을 수 있습니다. 이전 버전의 Laravel에 대한 문서를 읽을 수 있습니다.
등록 미들웨어
JWT 인증 확장 프로그램에는 이를 사용할 수 있는 미들웨어가 함께 제공됩니다. app/Http/Kernel.php에 auth.jwt 미들웨어를 등록하세요.
protected $routeMiddleware = [ .... 'auth.jwt' => \Tymon\JWTAuth\Http\Middleware\Authenticate::class, ];
이 미들웨어는 요청에 첨부된 토큰을 확인하여 사용자 인증을 확인합니다. 사용자가 인증되지 않으면 이 미들웨어는 UnauthorizedHttpException 예외를 발생시킵니다.
라우팅 설정
시작하기 전에 이 튜토리얼에서 논의한 모든 지점에 대한 라우팅을 설정하겠습니다. Routes/api.php를 열고 다음 경로를 파일에 복사하십시오.
Route::post('login', 'ApiController@login'); Route::post('register', 'ApiController@register'); Route::group(['middleware' => 'auth.jwt'], function () { Route::get('logout', 'ApiController@logout'); Route::get('user', 'ApiController@getAuthUser'); Route::get('products', 'ProductController@index'); Route::get('products/{id}', 'ProductController@show'); Route::post('products', 'ProductController@store'); Route::put('products/{id}', 'ProductController@update'); Route::delete('products/{id}', 'ProductController@destroy'); });
사용자 모델 업데이트
JWT는 사용자 모델에서 TymonJWTAuthContractsJWTSubject 인터페이스를 구현해야 합니다. 이 인터페이스는 getJWTIdentifier 및 getJWTCustomClaims 두 가지 메소드를 구현해야 합니다. 다음 내용으로 app/User.php를 업데이트하세요.
<?php namespace App; 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', ]; /** * 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 []; } }
JWT 인증 로직
JWT 인증을 이용하여 laravel에서 Restful API의 로직을 작성해 보겠습니다.
用户注册时需要姓名,邮箱和密码。那么,让我们创建一个表单请求来验证数据。通过运行以下命令创建名为 RegisterAuthRequest 的表单请求:
php artisan make:request RegisterAuthRequest
它将在 app/Http/Requests 目录下创建 RegisterAuthRequest.php 文件。将下面的代码黏贴至该文件中。
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class RegisterAuthRequest extends FormRequest { /** * 确定是否授权用户发出此请求 * * @return bool */ public function authorize() { return true; } /** * 获取应用于请求的验证规则 * * @return array */ public function rules() { return [ 'name' => 'required|string', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:6|max:10' ]; } }
运行以下命令创建一个新的 ApiController :
php artisan make:controller ApiController
这将会在 app/Http/Controllers 目录下创建 ApiController.php 文件。将下面的代码黏贴至该文件中。
<?php namespace App\Http\Controllers; use App\Http\Requests\RegisterAuthRequest; use App\User; use Illuminate\Http\Request; use JWTAuth; use Tymon\JWTAuth\Exceptions\JWTException; class ApiController extends Controller { public $loginAfterSignUp = true; public function register(RegisterAuthRequest $request) { $user = new User(); $user->name = $request->name; $user->email = $request->email; $user->password = bcrypt($request->password); $user->save(); if ($this->loginAfterSignUp) { return $this->login($request); } return response()->json([ 'success' => true, 'data' => $user ], 200); } public function login(Request $request) { $input = $request->only('email', 'password'); $jwt_token = null; if (!$jwt_token = JWTAuth::attempt($input)) { return response()->json([ 'success' => false, 'message' => 'Invalid Email or Password', ], 401); } return response()->json([ 'success' => true, 'token' => $jwt_token, ]); } public function logout(Request $request) { $this->validate($request, [ 'token' => 'required' ]); try { JWTAuth::invalidate($request->token); return response()->json([ 'success' => true, 'message' => 'User logged out successfully' ]); } catch (JWTException $exception) { return response()->json([ 'success' => false, 'message' => 'Sorry, the user cannot be logged out' ], 500); } } public function getAuthUser(Request $request) { $this->validate($request, [ 'token' => 'required' ]); $user = JWTAuth::authenticate($request->token); return response()->json(['user' => $user]); } }
让我解释下上面的代码发生了什么。
在 register 方法中,我们接收了 RegisterAuthRequest 。使用请求中的数据创建用户。如果 loginAfterSignUp 属性为 true ,则注册后通过调用 login 方法为用户登录。否则,成功的响应则将伴随用户数据一起返回。
在 login 方法中,我们得到了请求的子集,其中只包含电子邮件和密码。以输入的值作为参数调用 JWTAuth::attempt() ,响应保存在一个变量中。如果从 attempt 方法中返回 false ,则返回一个失败响应。否则,将返回一个成功的响应。
在 logout 方法中,验证请求是否包含令牌验证。通过调用 invalidate 方法使令牌无效,并返回一个成功的响应。如果捕获到 JWTException 异常,则返回一个失败的响应。
在 getAuthUser 方法中,验证请求是否包含令牌字段。然后调用 authenticate 方法,该方法返回经过身份验证的用户。最后,返回带有用户的响应。
身份验证部分现在已经完成。
构建产品部分
要创建产品部分,我们需要 Product 模型,控制器和迁移文件。运行以下命令来创建 Product 模型,控制器和迁移文件。
php artisan make:model Product -mc
它会在 database/migrations 目录下创建一个新的数据库迁移文件 create_products_table.php,更改 up 方法。
public function up() { Schema::create('products', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); $table->string('name'); $table->integer('price'); $table->integer('quantity'); $table->timestamps(); $table->foreign('user_id') ->references('id') ->on('users') ->onDelete('cascade'); }); }
向 Product 模型中添加 fillable 属性。在 app 目录下打开 Product.php 文件并添加属性。
protected $fillable = [ 'name', 'price', 'quantity' ];
现在在 .env 文件中设置数据库凭证,并通过运行以下命令迁移数据库。
php artisan migrate
现在,我们必须在 User 模型中添加一个关系来检索相关产品。在 app/User.php 中添加以下方法。
public function products() { return $this->hasMany(Product::class); }
在 app/Http/Controllers 目录下打开 ProductController.php 文件。在文件开头添加 use 指令覆盖上一个。
use App\Product; use Illuminate\Http\Request; use JWTAuth;
现在我们将实现五个方法。
index, 为经过身份认证的用户获取所有产品列表
show, 根据 ID 获取特定的产品
store, 将新产品存储到产品列表中
update, 根据 ID 更新产品详情
destroy, 根据 ID 从列表中删除产品
添加一个构造函数来获取经过身份认证的用户,并将其保存在 user 属性中。
protected $user; public function __construct() { $this->user = JWTAuth::parseToken()->authenticate(); }
parseToken 将解析来自请求的令牌, authenticate 通过令牌对用户进行身份验证。
让我们添加 index 方法。
public function index() { return $this->user ->products() ->get(['name', 'price', 'quantity']) ->toArray(); }
上面的代码非常简单,我们只是使用 Eloquent 的方法获取所有的产品,然后将结果组成一个数组。最后,我们返回这个数组。Laravel 将自动将其转换为 JSON ,并创建一个为 200 成功的响应码。
继续实现 show 方法。
public function show($id) { $product = $this->user->products()->find($id); if (!$product) { return response()->json([ 'success' => false, 'message' => 'Sorry, product with id ' . $id . ' cannot be found' ], 400); } return $product; }
这个也非常容易理解。我们只需要根据 ID 找到该产品。如果产品不存在,则返回 400 故障响应。否则,将返回产品数组。
接下来是 store 方法
public function store(Request $request) { $this->validate($request, [ 'name' => 'required', 'price' => 'required|integer', 'quantity' => 'required|integer' ]); $product = new Product(); $product->name = $request->name; $product->price = $request->price; $product->quantity = $request->quantity; if ($this->user->products()->save($product)) return response()->json([ 'success' => true, 'product' => $product ]); else return response()->json([ 'success' => false, 'message' => 'Sorry, product could not be added' ], 500); }
在 store 方法中,验证请求中是否包含名称,价格和数量。然后,使用请求中的数据去创建一个新的产品模型。如果,产品成功的写入数据库,会返回成功响应,否则返回自定义的 500 失败响应。
实现 update 方法
public function update(Request $request, $id) { $product = $this->user->products()->find($id); if (!$product) { return response()->json([ 'success' => false, 'message' => 'Sorry, product with id ' . $id . ' cannot be found' ], 400); } $updated = $product->fill($request->all()) ->save(); if ($updated) { return response()->json([ 'success' => true ]); } else { return response()->json([ 'success' => false, 'message' => 'Sorry, product could not be updated' ], 500); } }
在 update 方法中,我们通过 id 取得产品。如果产品不存在,返回一个 400 响应。然后,我们把请求中的数据使用 fill 方法填充到产品详情。更新产品模型并保存到数据库,如果记录成功更新,返回一个 200 成功响应,否则返回 500 内部服务器错误响应给客户端。
现在,让我们实现 destroy 方法。
public function destroy($id) { $product = $this->user->products()->find($id); if (!$product) { return response()->json([ 'success' => false, 'message' => 'Sorry, product with id ' . $id . ' cannot be found' ], 400); } if ($product->delete()) { return response()->json([ 'success' => true ]); } else { return response()->json([ 'success' => false, 'message' => 'Product could not be deleted' ], 500); } }
在 destroy 方法中,我们根据 ID 获取产品,如果产品不存在,则返回 400 响应。然后我们删除产品后并根据删除操作的成功状态返回适当的响应。
控制器代码现在已经完成,完整的控制器代码在这。
测试
我们首先来测试身份认证。我们将使用 serve 命令在开发机上启动 Web 服务,你也可以使用虚拟主机代替。运行以下命令启动 Web 服务。
php artisan serve
它将监听 localhost:8000
为了测试 restful API's,我们使用 Postman。填写好请求体之后,我们请求一下 register 路由。
요청을 보내면 토큰을 받게 됩니다.
이제 사용자가 등록 및 인증되었습니다. 로그인 경로를 감지하기 위해 또 다른 요청을 보내면 200과 토큰이 반환됩니다.
사용자 세부정보 가져오기
테스트 신원 인증이 완료되었습니다. 다음으로 제품 부분을 테스트하고 먼저 제품을 만듭니다.
이제 인덱스 방식을 요청하여 제품을 받아보세요.
다른 경로를 테스트해 보면 모두 잘 작동할 것입니다.
추천 튜토리얼: "Laravel Tutorial"
위 내용은 Laravel을 사용하여 JWT 인증을 통합하여 RestfulApi 개발의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!