我试图用Laravel的护照测试身份验证,没有办法...总是收到401的客户端是无效的,我会告诉你我试过什么:
我的phpunit配置是一个来自基地与拉威尔
abstract class TestCase extends BaseTestCase
{
use CreatesApplication, DatabaseTransactions;
protected $client, $user, $token;
public function setUp()
{
parent::setUp();
$clientRepository = new ClientRepository();
$this->client = $clientRepository->createPersonalAccessClient(
null, 'Test Personal Access Client', '/'
);
DB::table('oauth_personal_access_clients')->insert([
'client_id' => $this->client->id,
'created_at' => date('Y-m-d'),
'updated_at' => date('Y-m-d'),
]);
$this->user = User::create([
'id' => 1,
'name' => 'test',
'lastname' => 'er',
'email' => 'test@test.test',
'password' => bcrypt('secret')
]);
$this->token = $this->user->createToken('TestToken', [])->accessToken;
}
}
class AuthTest extends TestCase
{
use DatabaseMigrations;
public function testShouldSignIn()
{
// Arrange
$body = [
'client_id' => (string) $this->client->id,
'client_secret' => $this->client->secret,
'email' => 'test@test.test',
'password' => 'secret',
];
// Act
$this->json('POST', '/api/signin', $body, ['Accept' => 'application/json'])
// Assert
->assertStatus(200)
->assertJsonStructure([
'data' => [
'jwt' => [
'access_token',
'expires_in',
'token_type',
]
],
'errors'
]);
}
}
我方便的护照认证用于测试目的
Route::post('/signin', function () {
$args = request()->only(['email', 'password', 'client_id', 'client_secret']);
request()->request->add([
'grant_type' => 'password',
'client_id' => $args['client_id'] ?? env('PASSPORT_CLIENT_ID', ''),
'client_secret' => $args['client_secret'] ?? env('PASSPORT_CLIENT_SECRET', ''),
'username' => $args['email'],
'password' => $args['password'],
'scope' => '*',
]);
$res = Route::dispatch(Request::create('oauth/token', 'POST'));
$data = json_decode($res->getContent());
$isOk = $res->getStatusCode() === 200;
return response()->json([
'data' => $isOk ? [ 'jwt' => $data ] : null,
'errors' => $isOk ? null : [ $data ]
], 200);
});
我认为选择的答案可能是迄今为止最健壮和最好的,但我想提供一个替代方案,如果你只需要快速通过护照后的测试,而无需太多的设置。
重要提示:我认为如果你要做很多这件事,这不是正确的方法,其他答案更好。但在我看来,这似乎只是工作
这里是一个完整的测试用例,我需要假设一个用户,发布到一个endpoint,并使用他们的授权令牌发出请求。
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Models\User;
use Laravel\Passport\Passport;
class MyTest extends TestCase
{
use WithFaker, RefreshDatabase;
public function my_test()
{
/**
*
* Without Artisan call you will get a passport
* "please create a personal access client" error
*/
\Artisan::call('passport:install');
$user = factory(User::class)->create();
Passport::actingAs($user);
//See Below
$token = $user->generateToken();
$headers = [ 'Authorization' => 'Bearer $token'];
$payload = [
//...
];
$response = $this->json('POST', '/api/resource', $payload, $headers);
$response->assertStatus(200)
->assertJson([
//...
]);
}
}
为了清楚起见,这里是User模型中的GenerateToken()
方法,它利用了HasApiTokens
特性。
public function generateToken() {
return $this->createToken('my-oauth-client-name')->accessToken;
}
在我看来,这是相当粗糙和准备就绪的。例如,如果您使用的是ReFresDatabase
特性,您必须在每个方法中运行这样的护照:安装命令。通过全局设置可能有更好的方法来做到这一点,但我对PHPUnit相当陌生,所以这就是我的做法(目前)。
Laravel Passport实际上附带了一些测试助手,您可以使用这些助手来测试经过身份验证的APIendpoint。
Passport::actingAs(
factory(User::class)->create(),
);
这就是如何实现它,使它实际工作。
首先,您应该正确地实现db:seeds和Passport安装。
第二,您不需要创建自己的路径来验证,如果这样做有效的话(基本的Passport响应就足够了)。
下面是一个描述,关于它在我的安装(Laravel 5.5)中是如何工作的。。。
在我的例子中,我只需要一个Passport客户端,这就是为什么我创建了另一个路由,用于api授权(api/v1/login
),只提供用户名和密码。你可以在这里了解更多。
幸运的是,这个示例还包括基本的Passport授权测试。
因此,要成功运行测试,基本思路是:
PASSPORT\u CLIENT\u ID创建.env
条目(可选-PASSPORT始终使用空数据库上的ID=2创建密码授予令牌)。
- 使用此id从db获取正确的客户端密钥。
- 然后运行你的测试
代码示例。。。
ApiLoginTest.php
/**
* @group apilogintests
*/
public function testApiLogin() {
$body = [
'username' => 'admin@admin.com',
'password' => 'admin'
];
$this->json('POST','/api/v1/login',$body,['Accept' => 'application/json'])
->assertStatus(200)
->assertJsonStructure(['token_type','expires_in','access_token','refresh_token']);
}
/**
* @group apilogintests
*/
public function testOauthLogin() {
$oauth_client_id = env('PASSPORT_CLIENT_ID');
$oauth_client = OauthClients::findOrFail($oauth_client_id);
$body = [
'username' => 'admin@admin.com',
'password' => 'admin',
'client_id' => $oauth_client_id,
'client_secret' => $oauth_client->secret,
'grant_type' => 'password',
'scope' => '*'
];
$this->json('POST','/oauth/token',$body,['Accept' => 'application/json'])
->assertStatus(200)
->assertJsonStructure(['token_type','expires_in','access_token','refresh_token']);
}
笔记:
当然,凭证需要修改。
如前所述,PASSPORT\u CLIENT\u ID必须为2。
JsonStructure验证是冗余的,因为只有在授权成功的情况下,我们才能得到200个响应。但是,如果您需要额外的验证,这也会通过。。。
TestCase.php
public function setUp() {
parent::setUp();
\Artisan::call('migrate',['-vvv' => true]);
\Artisan::call('passport:install',['-vvv' => true]);
\Artisan::call('db:seed',['-vvv' => true]);
}
笔记:
在这里,我们将创建db的相关条目,这是我们测试中需要的。因此,请记住,要让具有角色等的用户在此处播种。
最后的笔记。。。
这应该足够了,让你的代码工作。在我的系统上,所有这些都是绿色的,也适用于我的gitlab CI跑步者。
最后,请在路线上检查您的中间件。特别是,如果你正在试验野狗(或thymon的jwt)包。
唯一可以考虑应用于护照授权路由的中间件是“代码>节流器< /代码>,以防止暴力攻击。
旁注...
Passport和dingo有完全不同的jwt实现。
在我的测试中,只有Passport的行为是正确的,我认为这就是为什么不再保留野狗的原因。
希望它能解决你的问题。。。
我们想使用Jitsi REST API创建一个会议。我们的Jitsi实例已经受到Prosody的保护:只有某些用户可以主持会议(他们必须使用用户和密码凭据进行身份验证才能主持会议室)。现在,在他们这么做之后,计划是通过创建一个来宾密码来保护房间,聊天伙伴/来宾需要输入该密码才能加入会议。这个过程需要通过REST API实现自动化:我们希望通过REST API创建会议,并传递一个需要来宾输入的密码。
我正在我的Web应用程序中构建聊天功能。我使用jitsi作为我们的聊天服务器。在视频聊天会话中可以有2-4个用户。这些会话将被锁定。Web应用程序将启动聊天,并将控制谁可以加入聊天室。 我试图嵌入jitsi满足内部使用jitsi满足外部API的网页这里列出https://github.com/jitsi/jitsi-meet/blob/master/doc/api.md。 我们的jitsi会议不向
在我配置了下面的配置之后,它不会连接到Active Directory。我无法使用Active Directory的帐户登录。会有什么问题? 我有一个Ubuntu服务器18.04,带有ApacheGuacamoleV1。0.0. 安装。我想使用LDAP身份验证来验证用户。我已经下载了鳄梨酱-auth-ldap-1.0.0。jar和jldap-4.3。jar扩展。 10.10.10.21,10.10
(我曾在SO上回顾过类似的问题,但没有一个建议对我有效) 我有一个API服务,运行在Google App Engine上(在Google云平台上)。我需要通过谷歌管理目录API的身份验证,以便我可以在我们的GSuite域上创建组。 我最初尝试了隐式授权,遵循指南,以手动获取和提供服务帐户凭据,但我认为这可能仅限于在Google App Engine上运行的应用程序之间的通信。我的理解是,在App
问题内容: 我们有一个Java EE 7应用程序,并使用Arquillian进行测试。现在,我们要检查当前登录用户的某些权限。我的问题很基本,在测试用例中时如何登录用户?我已经阅读了ProgrammaticLogin在Arquillian测试和Embedded Glassfish,安全性和Arquillian问题中不起作用,但是并没有明确回答。我当前的方法是这样的: 现在,当我尝试运行此命令时,将