使用 Lumen(v5.8) 构建 JWT 认证 API
在本教程中,我们将使用 Lumen(Laravel 开发的一款超快速微框架)来构建一个简单安全的 REST API。完成本教程后,您将能够构建可用于生产的 API。让我们开始吧!
先决条件
我恳求你,确保你拥有必需品。
- PHP >= 7.1.3
- OpenSSL PHP 扩展
- PDO PHP 扩展
- Mbstring PHP 扩展
- Mysql >= 5.7
- Composer(PHP 依赖管理器)
- Postman(用于测试您的端点)
安装
首先,您需要获取 lumen 的 cli。
$ composer global require "laravel/lumen-installer"
如果下载成功,请运行以下命令来确认您已安装流明。
$ lumen
如果遇到类似的错误-bash: lumen: command not found
,则需要将作曲家的供应商 bin 添加到您的路径中。
如果一切正常,您应该会看到类似这样的内容。
现在运行此命令来创建 lumen 项目
$ lumen new auth-app
进入项目文件夹
$ cd auth-app
运行应用
$ php -S localhost:8000 -t public
在您的浏览器地址栏上加载localhost:8000
,它将呈现如下所示的结果。
在您喜欢的编辑器中打开项目(auth-app)。
创建一个 .env 文件,将 .env.example 中的所有内容复制到 .env 文件中并添加数据库配置。
取消boostrap/app.php
注释外观和雄辩的方法
//before
// $app->withFacades();
// $app->withEloquent();
//after
$app->withFacades();
$app->withEloquent();
启用 withFacades 会将应用程序的 IoC 注入到 Illuminate\Support\Facades\Facade。如果不启用 withFacades,即使导入了 Illuminate\Support\Facades\File 也无法正常工作。
$app->withEloquent() 方法实际上也启用了查询构建器。它注册了 DatabaseServiceProvider,而使用查询构建器则需要它。致谢。
创建用户
进行用户数据库迁移
$ php artisan make:migration create_users_table --create=users
找到迁移文件database/migrations/*_create_users_table.php
并添加所需的表列(名称、电子邮件、密码);请参阅以下代码:
...
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique()->notNullable();
$table->string('password');
$table->timestamps();
});
}
...
迁移数据库
$ php artisan migrate
添加注册路由,顾名思义,用于注册用户。找到routes/web.php
并插入所需代码,如下所示
// API route group
$router->group(['prefix' => 'api'], function () use ($router) {
// Matches "/api/register
$router->post('register', 'AuthController@register');
});
由于我们要api
在所有端点上添加前缀,为了减少重复,我们将使用路由分组来做到这一点。
此方法 ($router->post($uri, $callback);
接受 $url 和 $callback 参数。在 中$callback
,AuthController
是我们的控制器类(我们将稍后创建此类)并且register
是该类中的方法。
让我们创建我们的 AuthControler。
创建文件app/Http/Controllers/AuthController.php
并用代码填充它,如下所示。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class AuthController extends Controller
{
/**
* Store a new user.
*
* @param Request $request
* @return Response
*/
public function register(Request $request)
{
//validate incoming request
$this->validate($request, [
'name' => 'required|string',
'email' => 'required|email|unique:users',
'password' => 'required|confirmed',
]);
try {
$user = new User;
$user->name = $request->input('name');
$user->email = $request->input('email');
$plainPassword = $request->input('password');
$user->password = app('hash')->make($plainPassword);
$user->save();
//return successful response
return response()->json(['user' => $user, 'message' => 'CREATED'], 201);
} catch (\Exception $e) {
//return error message
return response()->json(['message' => 'User Registration Failed!'], 409);
}
}
}
使用路线注册一个用户(使用 POSTMAN)localhost:8000/api/register
,您应该会得到一个成功的响应,如下所示
用户登录
拉取JWT认证包。
$ composer require tymon/jwt-auth:dev-develop
生成您的 API 密钥
$ php artisan jwt:secret
config/auth.php
使用以下配置创建文件
//config.auth.php
<?php
return [
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => \App\User::class
]
]
];
User
对你的model( )进行一些修改app/User.php
,以适应tymon/jwt-auth 的要求。请留意所有包含“JWT”的内容。
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Laravel\Lumen\Auth\Authorizable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
use Authenticatable, Authorizable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email'
];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'password',
];
/**
* 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 [];
}
}
做一些改变bootstrap/app.php
//before
// $app->routeMiddleware([
// 'auth' => App\Http\Middleware\Authenticate::class,
// ]);
//After
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]);
//before
// $app->register(App\Providers\AppServiceProvider::class);
// $app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
//After
// $app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
// Add this line
$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);
添加登录路由routes/web.php
// API route group
$router->group(['prefix' => 'api'], function () use ($router) {
// Matches "/api/register
$router->post('register', 'AuthController@register');
// Matches "/api/login
$router->post('login', 'AuthController@login');
});
在 Controller 类中添加一个全局的 respondWithToken 方法app/Http/Controllers/Controller.php
。这样我们就可以从任何其他控制器访问它。
...
//import auth facades
use Illuminate\Support\Facades\Auth;
//Add this method to the Controller class
protected function respondWithToken($token)
{
return response()->json([
'token' => $token,
'token_type' => 'bearer',
'expires_in' => Auth::factory()->getTTL() * 60
], 200);
}
在您的 AuthController 类中添加登录方法app/Http/Controllers/AuthController.php
...
//import auth facades
use Illuminate\Support\Facades\Auth;
...
/**
* Get a JWT via given credentials.
*
* @param Request $request
* @return Response
*/
public function login(Request $request)
{
//validate incoming request
$this->validate($request, [
'email' => 'required|string',
'password' => 'required|string',
]);
$credentials = $request->only(['email', 'password']);
if (! $token = Auth::attempt($credentials)) {
return response()->json(['message' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
使用路由登录用户localhost:8000/api/login
,您应该会得到如下成功响应:
已验证的路由
为了我们的压轴大戏,我们将制作一些经过验证的路线。
添加几条路线routes/web.php
...
// API route group
$router->group(['prefix' => 'api'], function () use ($router) {
// Matches "/api/register
$router->post('register', 'AuthController@register');
// Matches "/api/login
$router->post('login', 'AuthController@login');
// Matches "/api/profile
$router->get('profile', 'UserController@profile');
// Matches "/api/users/1
//get one user by id
$router->get('users/{id}', 'UserController@singleUser');
// Matches "/api/users
$router->get('users', 'UserController@allUsers');
});
...
创建一个文件app/Http/Controllers/UserController.php
并用这段优雅的代码填充它。
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\User;
class UserController extends Controller
{
/**
* Instantiate a new UserController instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Get the authenticated User.
*
* @return Response
*/
public function profile()
{
return response()->json(['user' => Auth::user()], 200);
}
/**
* Get all User.
*
* @return Response
*/
public function allUsers()
{
return response()->json(['users' => User::all()], 200);
}
/**
* Get one user.
*
* @return Response
*/
public function singleUser($id)
{
try {
$user = User::findOrFail($id);
return response()->json(['user' => $user], 200);
} catch (\Exception $e) {
return response()->json(['message' => 'user not found!'], 404);
}
}
}
以下是对三个新添加的端点之一的调用示例
完结啦!
我希望本文能对您有所帮助,并希望您能在不久的将来基于这些知识部署出色的 API。我也希望在评论区看到您的贡献。
再见。
文章来源:https://dev.to/ndiecodes/build-a-jwt-authenticated-api-with-lumen-2afm