在本文中,使用postman对《基于 Laravel 构建 & 测试 RESTful API》进行测试。
认证
新增 api_token 字段
在 Laravel 中实现 API 认证有多种方式(例如 Passport),但是本教程会使用一个非常简化的方式。
开始之前,首先添加 api_token 到 users 表:
php artisan make:migration --table=users adds_api_token_to_users_table
然后编写这个迁移文件:
class AddsApiTokenToUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('api_token', 60)->unique()->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['api_token']);
});
}
}
最后执行迁移命令作用于数据表:
php artisan migrate
创建注册接口
我们使用 RegisterController 来根据注册请求返回正确的响应。尽管 Laravel 开箱提供了认证功能,但是我们还是需要对其进行调整以便返回我们想要的响应数据。该控制器使用 RegistersUsers 来实现注册,实现逻辑如下:
public function register(Request $request)
{
// Here the request is validated. The validator method is located
// inside the RegisterController, and makes sure the name, email
// password and password_confirmation fields are required.
$this->validator($request->all())->validate();
// A Registered event is created and will trigger any relevant
// observers, such as sending a confirmation email or any
// code that needs to be run as soon as the user is created.
event(new Registered($user = $this->create($request->all())));
// After the user is created, he's logged in.
$this->guard()->login($user);
// And finally this is the hook that we want. If there is no
// registered() method or it returns null, redirect him to
// some other URL. In our case, we just need to implement
// that method to return the correct response.
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
我们只需要在 RegisterController 中实现 registered 方法即可。该方法接收 $request 和 $user 参数:
protected function registered(Request $request, $user)
{
$user->generateToken();
return response()->json(['data' => $user->toArray()], 201);
}
在 routes/api.php 中注册路由如下:
Route::post('register', 'Auth\RegisterController@register');
在上面的示例代码中,我们调用了 User 模型上的生成令牌方法,该方法现在不存在,需要手动添加:
public function generateToken()
{
$this->api_token = str_random(60);
$this->save();
return $this->api_token;
}
至此,注册接口编写完成,用户现在可以通过注册接口进行注册了,感谢 Laravel 开箱提供的认证字段验证功能,如果你需要调整验证规则的话可以到 RegisterController 中查看 validator 方法。
下面我们来简单测试下注册接口:
curl -X POST http://apidemo.test/api/register \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name": "学院君", "email": "[email protected]", "password": "test123", "password_confirmation": "test123"}'
使用postman测试如下:
如图,返回注册成功的信息。
创建登录接口
和注册接口一样,可以编辑 LoginController 控制器来支持 API 认证。为此,我们需要在 LoginController 覆盖 AuthenticatesUsers trait 提供的 login 方法:
public function login(Request $request)
{
$this->validateLogin($request);
if ($this->attemptLogin($request)) {
$user = $this->guard()->user();
$user->generateToken();
return response()->json([
'data' => $user->toArray(),
]);
}
return $this->sendFailedLoginResponse($request);
}
然后在 routes/api.php 中注册登录路由:
Route::post('login', 'Auth\LoginController@login');
现在,基于我们上面注册的新用户,我们来测试下登录接口:
curl -X POST http://apidemo.test/api/login \
-H "Accept: application/json" \
-H "Content-type: application/json" \
-d "{\"email\": \"[email protected]\", \"password\": \"test123\" }"
登录成功返回结果:
使用postman测试如下:
这里需要复制api_token的字段值,一会儿在测试api:auth路由组时需要使用到。
后面就可以拿着这个 api_token 作为令牌来请求需要认证的资源了。使用我们现有的策略,请求认证资源时,如果没有 token 或 token 错误,用户将会接收到未认证响应(401)。
创建退出接口
为了形成完整闭环,下面我们来编写退出登录接口,实现思路是用户发起退出登录请求时,我们将其对应的 token 字段值从数据库移除。
首先,在 routes/api.php 中注册路由:
Route::post('logout', 'Auth\LoginController@logout');
然后在 Auth\LoginController.php 中编写 logout 方法:
public function logout(Request $request)
{
$user = Auth::guard('api')->user();
if ($user) {
$user->api_token = null;
$user->save();
}
return response()->json(['data' => 'User logged out.'], 200);
}
使用该策略,一旦退出,用户的所有令牌都会失效,访问需要认证的接口都会拒绝访问(通过中间件实现),这需要和前端配合来避免用户在没有访问任何内容的权限下保持登录状态。
使用postman进行测试,需要在请求的body中带上参数api_token,也就是登陆时返回的token值。如图:
使用中间件限制访问
api_token 创建之后,我们就可以在路由文件中应用认证中间件了:
Route::middleware('auth:api')
->get('/user', function (Request $request) {
return $request->user();
});
我们可以使用 $request->user() 或 Auth 门面访问当前用户:
Auth::guard('api')->user(); // 登录用户实例
Auth::guard('api')->check(); // 用户是否登录
Auth::guard('api')->id(); // 登录用户ID
接下来,我们将之前定义的文章相关路由进行分组:
Route::group(['middleware' => 'auth:api'], function() {
Route::get('articles', 'ArticleController@index');
Route::get('articles/{article}', 'ArticleController@show');
Route::post('articles', 'ArticleController@store');
Route::put('articles/{article}', 'ArticleController@update');
Route::delete('articles/{article}', 'ArticleController@delete');
});
这样就不需要为每个路由设置中间件,现在看来虽然节省不了多少时间,但随着应用体量的增长,这样做的好处是保持路由的DRY(Don’t Repeat Yourself)。
再访问文章接口就需要认证了:
使用postman进行测试:
之前一直以为api_token应该放到cookie字段中,但是发现使用laravel的api:auth进行认证时,需要将api_token放在URI中。如图:
通过这个实例,就可以掌握laravel的api开发和postman的使用了。
参考连接:
https://laravelacademy.org/post/9153.html